I need to send a metting request for Outlook 2013 with a file attachment in C#.
I have already working code to send a request but i really have no idea how to add an attachment to this.
MailMessage message = new MailMessage();
message.To.Add("someMail");
message.Subject = "Test";
message.From = new MailAddress("myMail");
message.Body = "Test Test";
SmtpClient smtp = new SmtpClient("mySmtp");
StringBuilder str = new StringBuilder();
str.AppendLine("BEGIN:VCALENDAR");
str.AppendLine("VERSION:2.0");
str.AppendLine("METHOD:REQUEST");
str.AppendLine("BEGIN:VEVENT");
str.AppendLine(string.Format("DTSTAMP:{0:yyyyMMddTHHmmZ}", DateTime.UtcNow));
str.AppendLine(string.Format("DTSTART:{0}", startTime));
str.AppendLine(string.Format("DTEND:{0}", endTime));
str.AppendLine("LOCATION: Zürich");
str.AppendLine(string.Format("UID:{0}", Guid.NewGuid()));
str.AppendLine(string.Format("DESCRIPTION:{0}", message.Body));
str.AppendLine(string.Format("X-ALT-DESC;FMTTYPE=text/html:{0}", message.Body));
str.AppendLine(string.Format("SUMMARY:{0}", message.Subject));
str.AppendLine(string.Format("ORGANIZER:MAILTO:{0}", message.From.Address));
str.AppendLine(string.Format("ATTENDEE;CN=\"{0}\";RSVP=TRUE:mailto:{1}", message.To[0].DisplayName, message.To[0].Address));
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");
System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType("text/calendar");
ct.Parameters.Add("method", "REQUEST");
AlternateView avCal = AlternateView.CreateAlternateViewFromString(str.ToString(), ct);
message.AlternateViews.Add(avCal);
smtp.Send(message);
I hope someone can help
Thanks Ego
You can try Below code
MailMessage msg = new MailMessage();
byte[] byteArray = Encoding.UTF8.GetBytes(str.ToString());
Stream contentStream = new MemoryStream(byteArray);
Attachment attachment = new Attachment(contentStream, "calendar.ics", "text/calendar");
attachment.TransferEncoding = System.Net.Mime.TransferEncoding.Base64;
msg.Attachments.Add(attachment);
Related
I need to digitally sign email using s/mime. I've created a detached signature for my attachment but outlook can't open it: "Cannot open this item. Your Digital ID name cannot be found by the underlying security system". Certificate is installed on this PC and there is smth need to be tweaked in this code:
const int CHARS_IN_LINE = 64;
StringBuilder message = new StringBuilder();
message.AppendLine("Content-Type: multipart/signed; protocol=\"application/pkcs7-signature\";");
message.AppendLine(" boundary=\"__multipart-signed-boundary__\"");
message.AppendLine("Content-Transfer-Encoding: 7bit");
message.AppendLine("MIME-Version: 1.0");
message.AppendLine("Subject: " + tbMessageSubject.Text);
message.AppendLine();
message.AppendLine("--__multipart-signed-boundary__");
message.AppendLine("Content-Type: text/xml; charset=\"windows - 1251\"");
message.AppendLine("Content-Disposition: attachment; ");
message.AppendLine(" filename=\"" + Path.GetFileName(filename) + "\"");
message.AppendLine("Content-Transfer-Encoding: base64");
message.AppendLine();
var dataToSign = File.ReadAllBytes(filePath);
var base64Data = Convert.ToBase64String(dataToSign, Base64FormattingOptions.None);
var base64DataSb = new StringBuilder(base64Data);
for (int i = CHARS_IN_LINE; i < base64DataSb.Length; i += CHARS_IN_LINE + 2) // \r\n
base64DataSb.Insert(i, "\r\n");
message.AppendLine(base64DataSb.ToString());
message.AppendLine("--__multipart-signed-boundary__");
message.AppendLine("Content-Type: application/pkcs7-signature; name=\"smime.p7m\"");
message.AppendLine("Content-Transfer-Encoding: base64");
message.AppendLine("Content-Disposition: attachment; filename=smime.p7s");
message.AppendLine();
CmsSigner signer = new CmsSigner(clientCert);
SignedCms cms = new SignedCms(new ContentInfo(dataToSign), true);
cms.ComputeSignature(signer);
var signature = cms.Encode();
var base64Signature = Convert.ToBase64String(signature, Base64FormattingOptions.None);
var base64Sb = new StringBuilder(base64Signature);
for (int i = CHARS_IN_LINE; i < base64Sb.Length; i += CHARS_IN_LINE + 2) // \r\n
base64Sb.Insert(i, "\r\n");
message.AppendLine(base64Sb.ToString());
message.AppendLine();
message.AppendLine("--__multipart-signed-boundary__--");
message.AppendLine(".");
var stream = new MemoryStream(Encoding.ASCII.GetBytes(message.ToString()));
MailMessage mail = new MailMessage();
mail.From = new MailAddress(tbEmailFrom.Text);
mail.To.Add(new MailAddress(tbEmailTo.Text));
AlternateView alternateView = new AlternateView(stream, "application/pkcs7-mime; smime-type=signed-data; name=smime.p7m");
alternateView.TransferEncoding = TransferEncoding.SevenBit;
mail.AlternateViews.Add(alternateView);
SmtpClient client = new SmtpClient(host, port);
client.EnableSsl = chbUseSSL.Checked;
client.Send(mail);
Finally, the issue was in specified mediaType in AlternateView, the correct way:
AlternateView alternateView = new AlternateView(stream, "multipart/signed; protocol=\"application/pkcs7-signature\"; boundary=\"__multipart-signed-boundary__\"");
alternateView.TransferEncoding = TransferEncoding.SevenBit;
and thanks to jdweng, I was need to sign not the attachment, but the attachment with it's headers (first __multipart-signed-boundary with attachment)
i wrote a function using c# , that is sending a meeting request to an email address .
i want to modify this function just to be able to send the meeting request to more to more than one Recipients .
where should i set the code that is responsible for this , down here is my code that implements this
string startTime1 = Convert.ToDateTime(startTime).ToString("yyyyMMddTHHmmssZ");
string endTime1 = Convert.ToDateTime(endTime).ToString("yyyyMMddTHHmmssZ");
MailMessage msg = new MailMessage(mailfrom, emailto);
msg.Subject = Subject;
msg.Body = emailbody;
#region Calender Request
StringBuilder str = new StringBuilder();
str.AppendLine("BEGIN:VCALENDAR");
//PRODID: identifier for the product that created the Calendar object
str.AppendLine("PRODID:-//test //Outlook MIMEDIR//EN");
str.AppendLine("VERSION:2.0");
str.AppendLine("METHOD:REQUEST");
str.AppendLine("BEGIN:VEVENT");
str.AppendLine(string.Format("DTSTART:{0:yyyyMMddTHHmmssZ}", startTime1));//TimeZoneInfo.ConvertTimeToUtc("BeginTime").ToString("yyyyMMddTHHmmssZ")));
str.AppendLine(string.Format("DTSTAMP:{0:yyyyMMddTHHmmssZ}", DateTime.UtcNow));
str.AppendLine(string.Format("DTEND:{0:yyyyMMddTHHmmssZ}", endTime1));//TimeZoneInfo.ConvertTimeToUtc("EndTime").ToString("yyyyMMddTHHmmssZ")));
str.AppendLine(string.Format("LOCATION: {0}", "Location"));
// UID should be unique.
str.AppendLine(string.Format("UID:{0}", Guid.NewGuid()));
str.AppendLine(string.Format("DESCRIPTION:{0}", msg.Body));
str.AppendLine(string.Format("X-ALT-DESC;FMTTYPE=text/html:{0}", msg.Body));
str.AppendLine(string.Format("SUMMARY:{0}", msg.Subject));
str.AppendLine("STATUS:CONFIRMED");
str.AppendLine("BEGIN:VALARM");
str.AppendLine("TRIGGER:-PT15M");
str.AppendLine("ACTION:Accept");
str.AppendLine("DESCRIPTION:Reminder");
str.AppendLine("X-MICROSOFT-CDO-BUSYSTATUS:BUSY");
str.AppendLine("END:VALARM");
str.AppendLine("END:VEVENT");
str.AppendLine(string.Format("ORGANIZER:MAILTO:{0}", msg.From.Address));
str.AppendLine(string.Format("ATTENDEE;CN=\"{0}\";RSVP=TRUE:mailto:{1}", msg.To[0].DisplayName, msg.To[0].Address));
str.AppendLine("END:VCALENDAR");
System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType("text/calendar");
ct.Parameters.Add("method", "REQUEST");
ct.Parameters.Add("name", "meeting.ics");
AlternateView avCal = AlternateView.CreateAlternateViewFromString(str.ToString(), ct);
msg.AlternateViews.Add(avCal);
#endregion
SmtpClient client = new SmtpClient("smtp.outlook.com", 587);
client.UseDefaultCredentials = false;
client.Credentials = new System.Net.NetworkCredential("lma#test.com", "test1234");
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.EnableSsl = true;
client.Send(msg);
You can send many more with BCC or CC property
MailAddress bcc = new MailAddress("manager1#contoso.com");
msg.Bcc.Add(bcc);
The above two lines of code will just send the appointment(.ics) items, but it won't give the rsvp response back to the organizer. Also it will hide the Response options!!!
So you need to have the attendees set as like below code :
str.AppendLine(string.Format("ATTENDEE;CN=\"{0}\";RSVP=TRUE:mailto:{1}", msg.To[0].DisplayName, "manager1#contoso.com")); //Attendee 1
str.AppendLine(string.Format("ATTENDEE;CN=\"{0}\";RSVP=TRUE:mailto:{1}", msg.To[0].DisplayName, "manager2#contoso.com")); // Attendee 2
Use BCC or CC property
MailAddress bcc = new MailAddress("manager1#contoso.com");
msg.Bcc.Add(bcc);
You can add as many Recipients as you want
Bcc
Cc
I want to send the image in the body of the mail. Here, I am loading a chart based on the database records. I converted the chart into bytes by the following code:
string base64 = Request.Form[hfImageData.UniqueID].Split(',')[1];
byte[] bytes = Convert.FromBase64String(base64);
Now, I want to convert this bytes array into Image and to add the image in the body of the mail.
This is my send mail code:
MailMessage message = new MailMessage();
string fromEmail = "domain.com";
string fromPW = "12345";
string toEmail = "abcde#gmail.com";
message.From = new MailAddress(fromEmail);
message.To.Add(toEmail);
message.Subject = "Chart Mail";
message.Body = "Hi Team";
message.IsBodyHtml = true;
message.DeliveryNotificationOptions = DeliveryNotificationOptions.OnFailure;
SmtpClient smtpClient = new SmtpClient("domain.com", 1234);
smtpClient.EnableSsl = false;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
smtpClient.UseDefaultCredentials = false;
smtpClient.Credentials = new NetworkCredential(fromEmail, fromPW);
smtpClient.Send(message.From.ToString(), message.To.ToString(), message.Subject, message.Body);
In the above code, I want to convert the bytes to image and need to send in the body of the mail. Please suggest.
There is no need to convert the image into bytes.
All you gotta do is:
string attachmentPath = Environment.CurrentDirectory + #"\test.png";
Attachment inline = new Attachment(attachmentPath);
inline.ContentDisposition.Inline = true;
inline.ContentDisposition.DispositionType = DispositionTypeNames.Inline;
inline.ContentId = contentID;
inline.ContentType.MediaType = "image/png";
inline.ContentType.Name = Path.GetFileName(attachmentPath);
message.Attachments.Add(inline);
This will show the message in 'Inline' layout and not just as an attached image
I am using C# .NET 4.0 to send a signed SMTP mail message like so:
private void SendMailMessage(object data)
{
MailMessage message = new MailMessage();
message.From = new MailAddress(fromAddress);
message.To.Add(new MailAddress(emailTo));
message.Subject = "Subject";
message.IsBodyHtml = true;
message.Body += "Blah blah blah.";
byte[] messageBytes = Encoding.ASCII.GetBytes(message.Body);
SignedCms Cms = new SignedCms(new ContentInfo(messageBytes));
CmsSigner Signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, certificate);
Cms.ComputeSignature(Signer);
byte[] SignedBytes = Cms.Encode();
MemoryStream signedStream = new MemoryStream(SignedBytes);
AlternateView signedView = new AlternateView(signedStream, "application/pkcs7-mime; smime-type=signed-data;name=sig.p7m");
message.AlternateViews.Add(signedView);
SmtpClient client = new SmtpClient(smtpServer, int.Parse(smtpServerPort));
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Send(message);
message.Dispose();
client = null;
}
From what I can tell, this "works" in that if view the raw data of the message, I see the alternate view with a big PKCS signature in it. But Outlook doesn't recognize it. The Outlook client normally recognizes signed messages and attempts to validate them and puts a little certificate on the message and all that...
I want that... what am I missing?
Edit: I have made some progress on this on my own, but still having some trouble. Here is what the code looks like now:
private void SendMailMessage(string emailTo)
{
MailMessage message = new MailMessage();
message.From = new MailAddress(fromAddress);
message.To.Add(new MailAddress(emailTo));
message.Subject = "Special Delivery";
message.IsBodyHtml = false;
string body = "Content-Type: text/plain;charset=\"iso-8859-1\"\nContent-Transfer-Encoding: quoted-printable\n\nHere is some body text!";
byte[] messageBytes = Encoding.ASCII.GetBytes(body);
ContentInfo content = new ContentInfo(messageBytes);
SignedCms signedCms = new SignedCms(content, false);
CmsSigner Signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, certificate);
signedCms.ComputeSignature(Signer);
byte[] signedBytes = signedCms.Encode();
MemoryStream ms = new MemoryStream(signedBytes);
AlternateView av = new AlternateView(ms, "application/pkcs7-mime; smime-type=signed-data;name=smime.p7m");
message.AlternateViews.Add(av);
SmtpClient client = new SmtpClient(smtpServer, int.Parse(smtpServerPort));
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Send(message);
message.Dispose();
client = null;
}
Of note is that I left message.Body blank this time, only sending the AlternateView. Now, when I send this to an Outlook inbox, I get the padlock icon over my email, the S/MIME doodad kicks in and tries to verify the signer, but fails. The certificate used to sign the email is issued by a publically trusted CA. Edit: That's my fault, the certificate didn't have the "secure email" usage attribute. I'll get a new certificate.
When I send the same email to a Gmail address, I get a blank message with a *.p7m attachment on it that contains a bunch of garbage.
The code that gets this working in Outlook looks like this:
private void SendMailMessage(string emailTo)
{
MailMessage message = new MailMessage();
message.From = new MailAddress(fromAddress);
message.To.Add(new MailAddress(emailTo));
message.Subject = "Regarding your lottery winnings";
message.IsBodyHtml = false;
string body = "Content-Type: text/plain;charset=\"iso-8859-1\"\nContent-Transfer-Encoding: quoted-printable\n\nBlah blah blah blah blah blah.";
byte[] messageBytes = Encoding.ASCII.GetBytes(body);
ContentInfo content = new ContentInfo(messageBytes);
SignedCms signedCms = new SignedCms(content, false);
CmsSigner Signer = new CmsSigner(SubjectIdentifierType.IssuerAndSerialNumber, emailCert);
signedCms.ComputeSignature(Signer);
byte[] signedBytes = signedCms.Encode();
MemoryStream ms = new MemoryStream(signedBytes);
AlternateView av = new AlternateView(ms, "application/pkcs7-mime; smime-type=signed-data;name=smime.p7m");
message.AlternateViews.Add(av);
SmtpClient client = new SmtpClient(smtpServer, int.Parse(smtpServerPort));
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.Send(message);
message.Dispose();
client = null;
}
Using a valid certificate, of course. Now when I send this email and view it in Outlook, I get the certificate icon on the email, and the S/MIME control successfully validates the signature, and the text shows up just like I want it to without displaying the headers to the user.
Notice that I have to leave message.Body empty. Putting anything in message.Body will break it.
I below code is to send email by reading the template html, and it works fine. But now my question is how to pass Salutation customerName from my .net code to the template at run time.
StringBuilder strBlr = new StringBuilder();
string strHTML = string.Empty;
string strTempalteHtmlpath = string.Empty;
//create the mail message
MailMessage mail;
string strFrom = ConfigurationSettings.AppSettings["fromAddressForBT"];
string strSubject = "Thanks for choosing Email contact preference";
mail = new MailMessage(strFrom, customerDetails.EmailId);
mail.Subject = strSubject;
//Read Html Template File Path
strTempalteHtmlpath = Convert.ToString(ConfigurationSettings.AppSettings["TemplatePath"]);
strHTML = File.ReadAllText(strTempalteHtmlpath);
strBlr = strBlr.Append(strHTML);
mail.Body = strBlr.ToString();
mail.IsBodyHtml = true;
//first we create the Plain Text part
AlternateView plainView = AlternateView.CreateAlternateViewFromString(strBlr.ToString(), null, "text/plain");
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(strBlr.ToString(), null, "text/html");
mail.AlternateViews.Add(plainView);
mail.AlternateViews.Add(htmlView);
//send the message
SmtpClient smtpMail = new SmtpClient(ConfigurationSettings.AppSettings["smtpClient"]);
smtpMail.Send(mail);
mail.Dispose();
Thanks.
This is code for sendemail button
StreamReader sr = new StreamReader(Server.MapPath("Sendpage.htm"));
string body = sr.ReadToEnd();
sr.Close();
body = body.Replace("#NameFamily#", txtNameFamily.Text);
body = body.Replace("#Email#", txtEmail.Text);
body = body.Replace("#Tellphone#", txtTellphone.Text);
body = body.Replace("#Text#", txtText.Text);
body = body.Replace("#Date#", DateTime.Now);
string Time = Convert.ToString(DateTime.Now.ToShortTimeString());
body = body.Replace("#Time#", Time);
SendMail("email that you want to send to it", body);
this is sendmail function code:
private void SendMail(string To, string Body)
{
SmtpClient Mailing = new SmtpClient("mail.domain.com");
MailMessage Message = new MailMessage();
Message.From = new MailAddress("mail#domain.com", "Your name or company name");
Message.Subject = "Subject";
Message.SubjectEncoding = Encoding.UTF8;
Message.IsBodyHtml = true;
Message.BodyEncoding = Encoding.UTF8;
Message.Body = Body;
Message.To.Add(new MailAddress(To));
Mailing.UseDefaultCredentials = false;
NetworkCredential MyCredential = new NetworkCredential("mail#domain.com", "password");
Mailing.Credentials = MyCredential; Mailing.Send(Message);
}