Home » C# » [C#] Send email with attachment, footer & calendar invite (.net)

[C#] Send email with attachment, footer & calendar invite (.net)


Sending emails with attachments is a common task in many applications, whether it’s for sharing documents, images, or other files with recipients. In this article, we will explore how to send an email with a file attachment including inserting an image as a footer after the HTML body content, as well as creating a meeting invitation through ‘.ICS’ file attachment using C# code, making use of the built-in .NET framework classes.

The below screenshot shows a sample output generated through C# code which covers all the methods & logic required for sending an email via the SMTP server.

send smtp email with attachment using C# code in dotnet core


For sending emails, we need:

  • Email settings (SMTP server, port number, sender email credentials, recipient email addresses).
  • HTML Message/ body content.
  • File for Attachment.
  • File (Image) for adding logo in the footer section (using LinkedResource & AlternateView Classes).
  • Calendar invitations (.ics) file for a meeting request or Calendar invite. (Calendar Appointment As Email Attachment)

Let’s start implementing sending-email functionality in the .Net project using C# code, step-by-step.



Set Up Your Project


First, create a new C# application project in your preferred development environment.

For demo purposes, we will implement this code in the Web API project. The folder and file structure of the solution project is shown below.




Configuring Email Settings


To send an email, you need a valid SMTP (Simple Mail Transfer Protocol) server address, a valid email address for the sender, and the recipient’s email address.

We will use Gmail as SMTP server in our example. Ensure you have access to this basic information before proceeding.

1) smtp server = "smtp.gmail.com";
2) port = 587; // Change if your SMTP server uses a different port
3) sender email e.g., "[email protected]";
4) sender app password e.g., "sender_app_password";
5) recipient email e.g., "[email protected]"; 

Important – Configure Google Security:
Before proceeding further, please go to your google account and enable 2-Step Verification & generate an app password for authentication purpose as well as to establish a secure connection via code.
Check this link – How to enable 2-Step verification & set app passwords in your Google account.

Note:
Gmail Authentication is required for sending emails. Make sure you have enabled SSL security in your Gmail Settings so that application(code) can access your mailbox.
If the connection is not established through a secure channel (2-Step Verification) then you will get an authentication failed error message – “The SMTP server requires a secure connection or the client was not authenticated. The server response was: 5.5.1 Authentication Required.”

SMTP server requires a secure connection or the client was not authenticated



Sending Email With Content, Attachments & calendar invite – C# code


Next, we’ll create separate classes and methods that send an email with attachments. In this example, we’ll send a simple text email with a single attachment, footer logo image & meeting request(.ics file) but you can customize it to suit your needs.


Step 1: Create {get set} email property class


Create a property class (MailTemplateProperty.cs) that will serve and get all the essential details for sending an email, such as the SMTP server address, valid email addresses for both the sender and recipient, as well as any attachments such as files, footers, and calendar invite/appointment information.


public class MailTemplateProperty
{
	// "SMTP Configuration/Credential"
	public string SmtpClientHost { get; set; }
	public int SmtpClientPort { get; set; }
	public bool SmtpClientEnableSSL { get; set; }
	public string CredentialUserName { get; set; }
	public string CredentialPass { get; set; }

	// "Compose Email"
	public string SenderName { get; set; }
	public string MailFrom { get; set; }
	public string MailTo { get; set; }
	public string MailCC { get; set; }
	public string Subject { get; set; }
	public string Body { get; set; }


	/* ===== Optional Setting ===== */

	// "File attachments"
	public Attachment Attachment { get; set; } = null;

	// "Adding logo/image on footer"
	public string Footer { get; set; } = null;

	// Attach Calendar or meeting properties
	public string StartDateTime { get; set; }
	public string EndDateTime { get; set; }
	public string EventLink { get; set; }
	public string EventLocation { get; set; }
	public string Attendee { get; set; }
} 


Step 2: Create a Class & methods to send mail


It is a good practice to keep all email-sending related functionalities in a separate Class. We create a class called ‘Mail.cs‘ with a function called ‘Send()‘ inside. This function sends an email using the details you provide.

We need to implement all mail-related logic and code implementation in this class, such as:

a) File attachment

Use the Attachment Class from ‘System.Net.Mail’ Namespace. In this example, the code shows that you can pass a file as a parameter either by passing ‘file as MemoryStream with the name’ or mentioning the full physical path & name of the file.

We need to use LinkedResource & AlternateView Classes in the mail code to display embedded image(s) in the footer section. How to work with Alternate view – To add an alternate view to a MailMessage object, create an Attachment for the view, and then add it to the collection returned by AlternateViews. Use the Body property to specify the text version and use the AlternateViews collection to specify views with other MIME types.

c) Calendar Appointment As Email Attachment (.ics)

Calendar invitation or ‘. ics’ file is a calendar file saved in a universal calendar format used by several email and calendar programs, including Google Calendar, Microsoft Outlook, and Apple Calendar. It allows adding a calendar link in an email message and users to share the event information on the web and over email which will alert/ remind recipients prior to scheduled meeting time.

d) Common logic

  • accepting mail body (plain text or HTML as string) and subject text
  • Getting mandatory credential info so that mail can be sent without any failure

All of these functionalities & logic have been incorporated in the code provided below.



Mail.cs – full code – just copy & paste

Ensure you have added the necessary namespace for email functionality.


using System.Net;
using System.Net.Mail;
using System.Net.Mime;
using System.Text; 

Code implementation.

public class Mail
{
	

// Main method for sending mail

public static bool Send(MailTemplateProperty mailTemplate) { string meetingMessageBody = mailTemplate.Body; mailTemplate.MailFrom = mailTemplate.MailFrom.Trim(',').Trim(';'); if (string.IsNullOrEmpty(mailTemplate.MailFrom)) return false; try { MailMessage mailMessage = new MailMessage { From = new MailAddress(mailTemplate.MailFrom, string.IsNullOrEmpty(mailTemplate.SenderName) ? mailTemplate.MailFrom : mailTemplate.SenderName), Subject = mailTemplate.Subject, Body = mailTemplate.Body, IsBodyHtml = true };

// Adding File Attachment

if (null != mailTemplate.Attachment) mailMessage.Attachments.Add(mailTemplate.Attachment);

// Adding To & CC email addresses,

mailTemplate.MailTo = mailTemplate.MailTo.Trim(); mailMessage.To.Add(mailTemplate.MailTo); if (!string.IsNullOrEmpty(mailTemplate.MailCC) && mailTemplate.MailCC.Length > 0) mailMessage.CC.Add(mailTemplate.MailCC);

// Adding logo-Image as Footer

if (mailTemplate.Footer != null) { LinkedResource res = new LinkedResource(mailTemplate.Footer) { ContentId = Guid.NewGuid().ToString() }; mailTemplate.Body += @"<img src='cid:" + res.ContentId + @"'/>"; AlternateView avHtml = AlternateView.CreateAlternateViewFromString(mailTemplate.Body, null, MediaTypeNames.Text.Html); avHtml.LinkedResources.Add(res); mailMessage.AlternateViews.Add(avHtml); }

// Adding Meeting Request

byte[] byteArray = Encoding.ASCII.GetBytes(MeetingRequestString(mailTemplate.Subject, meetingMessageBody, mailTemplate)); MemoryStream stream = new MemoryStream(byteArray); Attachment attach = new Attachment(stream, "event-meeting.ics"); mailMessage.Attachments.Add(attach);

// Finally, sending mail via Gmail, SMTP client info with credentials.

SmtpClient smtpClient = new SmtpClient { Host = mailTemplate.SmtpClientHost, Port = mailTemplate.SmtpClientPort, EnableSsl = mailTemplate.SmtpClientEnableSSL, Credentials = new NetworkCredential(mailTemplate.CredentialUserName, mailTemplate.CredentialPass), };

// Send mail by SMTP.

smtpClient.Send(mailMessage); return true; } catch (SmtpFailedRecipientException ex) { // LogError(ex.ToString()); return false; //throw new Exception(); } catch (SmtpException ex) { // LogError(ex.ToString()); return false; //throw new Exception(); } catch (Exception ex) { // LogError(ex.ToString()); return false; //throw new Exception(); } }

// Email Meeting Request- ics meeting/ Calendar invite Code

// Attaching calendar appointment

private static string MeetingRequestString(string subject, string messageBody, MailTemplateProperty mailTemplate, int? eventID = null, bool isCancel = false) { StringBuilder str = new StringBuilder(); str.AppendLine("BEGIN:VCALENDAR"); str.AppendLine("PRODID:-//Microsoft Corporation//Outlook 12.0 MIMEDIR//EN"); str.AppendLine("VERSION:2.0"); str.AppendLine(string.Format("METHOD:{0}", (isCancel ? "CANCEL" : "REQUEST"))); str.AppendLine("METHOD:REQUEST"); str.AppendLine("BEGIN:VEVENT"); str.AppendLine(string.Format("CREATED:{0:yyyyMMddTHHmmssZ}", DateTime.Now.ToUniversalTime())); // Date format - yyyyMMddTHHmmssZ str.AppendLine(string.Format("DTSTART:{0}", mailTemplate.StartDateTime)); str.AppendLine(string.Format("DTSTAMP:{0:yyyyMMddTHHmmss}", DateTime.Now.ToUniversalTime())); str.AppendLine(string.Format("DTEND:{0:}", mailTemplate.EndDateTime)); str.AppendLine(string.Format("LAST-MODIFIED:{0:yyyyMMddTHHmmssZ}", DateTime.Now.ToUniversalTime())); // web meeting link str.AppendLine(string.Format("LOCATION: {0}", mailTemplate.EventLink)); //or //str.AppendLine(string.Format("LOCATION: {0}", mailTemplate.EventLocation)); str.AppendLine("PRIORITY: 5"); str.AppendLine("SEQUENCE: 0"); str.AppendLine(string.Format("UID:{0}", (eventID.HasValue ? "EventId" + eventID : Guid.NewGuid().ToString()))); str.AppendLine(string.Format("DESCRIPTION:{0}", messageBody.Replace("\n", "<br>"))); str.AppendLine(string.Format("X-ALT-DESC;FMTTYPE=text/html:{0}", messageBody.Replace("\n", "<br>"))); str.AppendLine(string.Format("SUMMARY:{0}", subject)); str.AppendLine("STATUS:CONFIRMED"); str.AppendLine(string.Format("ORGANIZER;CN={0}:MAILTO:{1}", mailTemplate.MailFrom, mailTemplate.MailFrom)); str.AppendLine(string.Format("ATTENDEE;CN={0};RSVP=TRUE:mailto:{1}", string.Join(",", mailTemplate.Attendee), string.Join(",", mailTemplate.Attendee))); str.AppendLine("BEGIN:VALARM"); str.AppendLine("TRIGGER:-PT15M"); str.AppendLine("ACTION:DISPLAY"); str.AppendLine("DESCRIPTION:Reminder"); str.AppendLine("END:VALARM"); str.AppendLine("END:VEVENT"); str.AppendLine("END:VCALENDAR"); return str.ToString(); } }

Note:
In this example, code will return a true (bool) value if mail is sent successfully else a false value in case of any exception(failure). You can log errors or implement other logic in the catch{} section or modify method behaviour as per your need.


Step 3: Call & execute Mail.Send() Method


Common C# code for sending email via SMTP is completed. Now we can call & execute this Mail.Send() method from Controller (SendEmails.cs) or another code page in two steps:

a) Set all Property values

Before calling the Mail.Send() method, set all necessary property values (get all input & assign its values), see the sample below.


MailTemplateProperty mailTemplate = new MailTemplateProperty
{
	// "Gmail SMTP Configuration/Credential"
	SmtpClientHost = "smtp.gmail.com",
	SmtpClientPort = 587,
	SmtpClientEnableSSL = true,
	CredentialUserName = "[email protected]",
	CredentialPass = "google_app_password",

	// "Compose Email"
	SenderName = "Admin",
	MailFrom = "[email protected]",
	MailTo = "[email protected]",
	MailCC = string.Empty,
	Subject = "Next Team Meeting",
	Body = "This is a test mail from admin.",

	// "File attachments"
	//Attachment = new System.Net.Mail.Attachment(mailAttachmentFile.OpenReadStream(), "Meeging.pdf"),
	// or
	Attachment = new System.Net.Mail.Attachment(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "/Files/Meeting.pdf"),

	// "Adding logo/image on footer"
	Footer = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "/Images/MailFooterLogo.png",

	// Attach Calendar or meeting properties
	StartDateTime = DateTime.Now.ToUniversalTime().ToString("yyyyMMddTHHmmssZ"),
	EndDateTime = DateTime.Now.AddHours(1).ToUniversalTime().ToString("yyyyMMddTHHmmssZ"),
	// MS Teams or Skype or webex meeting link
	EventLink = "https://www.webex.com/test-meeting.html",
	EventLocation = "Online",
	Attendee = "[email protected]"
};


b) Finally, Call Mail.Send() Method

Now, call Mail.Send() method by passing ‘mailTemplate‘ object as a parameter.



Mail.Send(mailTemplate); 


That’s it, test the code. if sending mail is successful then the recipient(s) will receive the email in a few seconds. In case of failure, it will return false status as a bool value.
But you can also log an error or throw an exception based on your requirement.


Screenshots

Method 1:

You can get the file attachment from Azure blob storage but in this example, the Meeting.pdf file is attached from the Root folder, see the below screenshot.

send mail attachment from solution root folder


Method 2:

You can use IFormFile to receive a file as input from the front-end application and send it as an attachment, please see the implementation in the screenshot.



Download Source Code and try it yourself (open sample project using Visual Studio 2022)




  1. Anonymous says:

    i want this code file

    1. admin says:

      Sure, I will share this code project today.

  2. babi says:

    i want this code project please share it ..

    1. admin says:

      Sure, give me some time. Let me test this functionality in a new project, separately, then I will upload it. Update you soon.

    2. admin says:

      I have updated the Post and uploaded the Source Code as well. You can try it.

      https://www.codeindotnet.com/send-email-attachment-footer-meeting-invite/#download-source-code

Leave a Reply

Your email address will not be published. Required fields are marked *