Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Tim Corey
1h 11m 27s
Welcome to a comprehensive look at sending emails in a C# Windows Forms application using the insights from Tim Corey's "C# App Start To Finish - Lesson 26." In this lesson, Tim demonstrates how to build functionality that emails users, particularly in the context of a tournament tracker application.
Transactional emails - automated, personalized messages triggered by user actions - are essential for modern web applications. C# web applications often rely on transactional email APIs, such as Mailgun and SendGrid, for reliable and scalable delivery of production-ready emails.
This article will guide you through the process Tim demonstrates, including deciding where to place the email code, creating helper methods, building dynamic emails, and sending them using the built-in C# libraries. Visual Studio is the primary IDE for developing and testing email functionality in C# applications.
Email delivery platforms like Mailtrap can be used to monitor deliverability and test email sending during development.
Tim begins by reminding us of the core requirement: only one round of a tournament can be played at a time. This means that once a round is completed, teams need to be notified about their next match. These notification emails are a type of transactional email, typically sent automatically in response to user actions in web applications. Email is a practical solution to ensure participants are informed promptly, and Tim walks through building this functionality step by step.
Using a dedicated email service, such as Amazon SES, can help ensure reliable and scalable delivery of these transactional emails.
Tim starts by addressing a crucial question: Where should the email logic go? He explains that it should be placed where the application is already performing key tournament logic. In this case, the best place is inside the UpdateTournamentResults method.
Why here? Because this method handles:
By placing the email logic here, we only send emails after a round is completed, avoiding spamming users unnecessarily.
Tim introduces a strategy of tracking the current round before and after updating results:
To determine if a round has changed, Tim creates an extension method called CheckCurrentRound. This method iterates through all rounds in the tournament model and checks if every matchup in a round has a winner.
Tim emphasizes that starting the output at 1 handles cases where no rounds are complete yet. By using this method, the application can dynamically detect when a new round starts and trigger emails.
Tim advocates creating a dedicated EmailLogic class. This approach:
Using a dedicated email client library, such as MailKit, is recommended for modern C# applications, as it provides robust features and better support compared to the outdated SmtpClient class.
He sets up a public static method called SendEmail with parameters:
The BodyBuilder class from MailKit can be used to construct HTML emails and add attachments efficiently, making it easier to send emails with files such as PDFs.
Tim suggests keeping it simple for the first version, with CC and BCC added later if needed.
Once the current round is determined, Tim extracts a list of matchups for that round using LINQ. Each matchup contains entries for two competing teams.
For each matchup, he loops through:
This ensures every individual receives an email about their upcoming matchup. When sending emails to multiple recipients, the InternetAddressList class and the AddRange method can be used to efficiently add all recipient email addresses at once. It is also important to verify each recipient email address to ensure successful delivery.
Tim emphasizes the importance of gathering all necessary information, such as:
Tim then focuses on building the email subject and body dynamically:
When generating the email content, Tim considers whether to send a plain text email or an HTML email. Plain text emails are simple, compatible with all email clients, and often used for internal notifications or transactional messaging. HTML emails, on the other hand, allow for richer formatting. Sending both HTML and plain text versions can improve deliverability and ensure compatibility with various email service providers. You can send HTML emails in C# by setting the IsBodyHtml property of the MailMessage class to true, or by using the MailKit library and modifying the message body to include HTML content.
Using StringBuilder allows the application to:
Tim also handles special cases, like a bye week, where a team doesn't have an opponent.
Before sending, Tim checks that the participant has a valid email address. He notes:
This step ensures that only participants who provided emails receive notifications.
Tim explains that the sender email should be stored in App.config for flexibility. He adds:
Many email services, such as Amazon SES, require domain verification to ensure proper deliverability and avoid spam filters. This process involves adding and verifying your domain before you can reliably send emails through their API.
Later, a GlobalConfig helper retrieves these values. This abstraction allows the sender information to be changed without modifying the email logic code.
To send emails, Tim uses the System.Net.Mail namespace, which is built into C#. Steps include:
The MailMessage class allows you to add attachments using the Attachments property. You can send HTML emails in C# by setting the IsBodyHtml property of the MailMessage class to true.
Finally, Tim sets up the SMTP client to send the email:
Amazon SES (Simple Email Service) is a cost-effective and scalable email service offered by AWS to send transactional emails quickly. To integrate Amazon SES into your C# application, you need to install the AWS SES Package, and you may need to use an authentication token for secure access. Secure app access is important when configuring SMTP settings, especially when using services like Gmail or Office365, to ensure proper authentication and security.
He notes that email servers often enforce restrictions on the "From" address for security, and testing with a dummy or sandbox server is recommended.
To recap Tim's process:
For sending transactional emails at scale, it's recommended to use transactional email APIs such as SendGrid or Mailgun. Many services offer a free plan for initial testing - SendGrid, for example, allows you to send 100 emails per day and provides analytics for email performance. Always use environment variables or secure vaults like Azure Key Vault or AWS Secrets Manager to store sensitive credentials in your C# applications. During development, you can use .NET run to start your application and test email sending functionality.
Tim emphasizes abstraction and modularity: by isolating email logic, the application becomes easier to maintain, test, and expand.
Tim Corey's lesson demonstrates that sending emails in a C# application is more than just calling SmtpClient.Send(). It requires careful consideration of when to send emails, gathering relevant information, validating recipients, and structuring code for maintainability. The .NET framework provides robust support for email sending via the Simple Mail Transfer Protocol (SMTP), which is the most common way of sending emails from a C# application.
By following Tim's approach, developers can build robust, reusable email functionality that can scale with their applications, whether it's a tournament tracker, notification system, or other user-based services. Using modern libraries and protocols like SMTP ensures reliable and maintainable email functionality in C# applications.
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!
Join our newsletter, you’ll get exclusive access on article updates. We value your privacy