Two questions about ical.net - c#

I need send reminders to users of a web application.
To do this I use iCal.Net from nuget packages. Following instructions about the usage I'm able to send an email with an attachment containing the ics file.
My first question is: is it possible to send the message as appointment and not as attachment, so the user can avoid open it and then save the date?
Second: is it possible to format the event description as html and make it working on both Outlook office client and Chrome calendar? On these clients I see plain text representation with all the html tags. I tested also on Windows 10 calendar where the event description is correctly displayed as html.
Do I have to set something more?
This is my calendar string generation
var now = DateTime.Now;
var later = scadenza.Value;
var e = new Event
{
DtStart = new CalDateTime(later),
DtEnd = new CalDateTime(later),
Description = mailText,
IsAllDay = true,
Created = new CalDateTime(DateTime.Now),
Summary = $"Reminder for XYZ",
};
var attendee = new Attendee
{
CommonName = "…..",
Rsvp = true,
Value = new Uri("mailto:" + ConfigurationManager.AppSettings["ReminderReceiver"])
};
e.Attendees = new List<IAttendee> { attendee };
var calendar = new Calendar();
calendar.Events.Add(e);
var serializer = new CalendarSerializer(new SerializationContext());
var icalString = serializer.SerializeToString(calendar);
And this is for sending the reminder; note that if I don't "attach" the ics, the alternate view seems to be ineffective.
var message = new MailMessage();
message.To.Add(new MailAddress(receiverRecipient));
message.From = new MailAddress(senderRecipient);
message.Subject = messageTitle;
message.Body = "The attachment contains the reminder";
message.IsBodyHtml = true;
var smtpClient = new SmtpClient(ConfigurationManager.AppSettings["SmtpSrv"], Convert.ToInt32(ConfigurationManager.AppSettings["SmtpPort"]));
var cred = new NetworkCredential(ConfigurationManager.AppSettings["SmtpUser"], ConfigurationManager.AppSettings["SmtpPwd"]);
smtpClient.Credentials = cred;
System.Net.Mime.ContentType contype = new System.Net.Mime.ContentType("text/calendar");
contype.Parameters.Add("method", "REQUEST");
contype.Parameters.Add("name", "Scadenza.ics");
AlternateView avCal = AlternateView.CreateAlternateViewFromString(icalString, contype);
message.AlternateViews.Add(avCal);
message.Attachments.Add(new Attachment(GenerateStreamFromString(icalString), contype));
smtpClient.Send(message);

Related

iCal.Net events working fine in Gmail but not for Outlook

I am using iCal.Net to send meeting invitations. It's working fine on Gmail and it's showing me event like:
But on Outlook it's not showing me any invite like accept, tentative, and decline options. It's showing me like:
It should be shown like this:
Here is my code:
async Task<SendResponse> CreateCalendarEventAsync(
CalendarNotificationModel calendarNotificationModel)
{
var attendees = calendarNotificationModel.Attendees.Select(x => new
Ical.Net.DataTypes.Attendee()
{
CommonName = x.AttendeeName,
ParticipationStatus = "REQ-PARTICIPANT",
Rsvp = true,
Role = "REQ-PARTICIPANT",
Value = new Uri($"mailto:{x.AttendeeEmail}")
}).ToList();
var e = new CalendarEvent
{
Summary = calendarNotificationModel.Name,
IsAllDay = true,
Organizer = new Organizer()
{
CommonName = "HRMatrix",
Value = new Uri("mailto:xyz#zxy.com")
},
Attendees = attendees,
Status = "Confirmed",
Sequence = 0,
Start = new CalDateTime(calendarNotificationModel.StartDateTime),
End = new CalDateTime(calendarNotificationModel.EndDateTime),
Transparency = TransparencyType.Opaque,
Location = calendarNotificationModel.Location,
Description = calendarNotificationModel.Description
};
var calendar = new Calendar();
calendar.AddProperty("X-MS-OLK-FORCEINSPECTOROPEN", "TRUE");
calendar.AddProperty("METHOD", "REQUEST");
calendar.Events.Add(e);
var serializer = new CalendarSerializer();
var serializedCalendar = serializer.SerializeToString(calendar);
var bytesCalendar = Encoding.ASCII.GetBytes(serializedCalendar);
MemoryStream ms = new MemoryStream(bytesCalendar);
using (ms)
{
ms.Position = 0;
SmtpClient smtp = new SmtpClient
{
//The address of the SMTP server (I'll take mailbox 126 as an example, which can
be set according to the specific mailbox you use)
Host = "smtp.gmail.com",
EnableSsl = true,
Port = 587,
DeliveryMethod = SmtpDeliveryMethod.Network,
//Enter the user name and password of your sending SMTP server here
Credentials = new NetworkCredential("xyz#xyz", "sdfsdfsdfsdf")
};
//Set default sending information
Email.DefaultSender = new SmtpSender(smtp);
var email = Email
//Sender
.From("xyz#xyz")
//Addressee
.To("denis#org.com")
//Message title
.Subject("Interview")
//Email content
.Body("You are invited.");
//Determine whether the transmission is successful according to the transmission
result
var attachment = new FluentEmail.Core.Models.Attachment
{
Data = ms,
ContentType = "text/calendar",
Filename = "invite.ics",
};
email.Attach(attachment);
var result = email.Send();
//Or send it asynchronously
//await email.SendAsync();
return result;
}
}
Here is my .ics file:
BEGIN:VCALENDAR
METHOD:Request
PRODID:-//github.com/rianjs/ical.net//NONSGML ical.net 4.0//EN
VERSION:2.0
X-MS-OLK-FORCEINSPECTOROPEN:TRUE
BEGIN:VEVENT
ATTENDEE;CN=XYZ;PARTSTAT=REQ-PARTICIPANT;RSVP=TRUE;ROLE=REQ-PARTICIPA
NT:mailto:XYZ#hotmail.com
DESCRIPTION:You are invited to give an interview
DTEND:20220208T091006
DTSTAMP:20220207T181006Z
DTSTART:20220208T041006
LOCATION:Pakistan
ORGANIZER;CN=HRMatrix:mailto:xyz#gmail.com
SEQUENCE:0
STATUS:Confirmed
SUMMARY:XYZ
TRANSP:OPAQUE
UID:b2ddc1ef-a2e4-4b0e-afa0-27d9689fbsdf
END:VEVENT
END:VCALENDAR
PS: if I send the above .ics file from Gmail client it works but it does not work from my SMTP client.
Hi you can try adding attachment charset to "charset=UTF-8" when sending an email or 'mime' => 'text/calendar; method=REQUEST; charset=UTF-8'.

Changing name of automatic attached file in e-mail

I am using Mailkit library to send e-mails. This is the code to do so:
public async Task SendAsync(IdentityMessage message)
{
if (message == null)
return;
LinkedResource inline = new LinkedResource(System.Web.Hosting.HostingEnvironment.MapPath($"~/Images/logo.png"))
{
ContentId = Guid.NewGuid().ToString(),
ContentType = new ContentType("image/png")
{
Name = "logo.png"
}
};
var htmlBody = message.Body.Replace("{CID:LOGO}", String.Format("cid:{0}", inline.ContentId));
AlternateView avHtml = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);
avHtml.LinkedResources.Add(inline);
using (MailMessage objMailMsg = new MailMessage())
{
objMailMsg.AlternateViews.Add(avHtml);
objMailMsg.Body = htmlBody;
objMailMsg.Subject = message.Subject;
objMailMsg.BodyEncoding = Encoding.UTF8;
Properties.Settings.Default.Reload();
string fromEmail = Properties.Settings.Default.FromMail;
string fromName = Properties.Settings.Default.FromName;
string smtpPassword = Properties.Settings.Default.PwdSmtp;
objMailMsg.From = new MailAddress(fromEmail, fromName);
objMailMsg.To.Add(message.Destination);
objMailMsg.IsBodyHtml = true;
MimeMessage mime = MimeMessage.CreateFromMailMessage(objMailMsg);
HeaderId[] headersToSign = new HeaderId[] { HeaderId.From, HeaderId.Subject, HeaderId.Date };
string domain = "example.cl";
string selector = "default";
DkimSigner signer = new DkimSigner(#"C:\inetpub\dkim.pem", domain, selector)
{
HeaderCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Relaxed,
BodyCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Simple,
AgentOrUserIdentifier = "#contact.example.cl",
QueryMethod = "dns/txt",
};
mime.Prepare(EncodingConstraint.EightBit);
signer.Sign(mime, headersToSign);
using (SmtpClient smtpClient = new SmtpClient())
{
await Task.Run(() =>
{
try
{
smtpClient.Connect(Properties.Settings.Default.ServidorSmtp, Properties.Settings.Default.PuertoSmtp, Properties.Settings.Default.SSLSmtp);
smtpClient.Authenticate(fromEmail, smtpPassword);
smtpClient.Send(mime);
smtpClient.Disconnect(true);
}
catch (Exception ex)
{
ErrorLog.Save(ex);
//InfoLog.Save(htmlBody);
}
});
}
}
}
Well.. when the e-mail arrives, e-mail client shows it correctly in HTML format. However, an HTML file is attached in the e-mail also.
That file is named, for example, Attached data without title 00391.html. If I open that file in browser, the e-mail body is shown.
I have not found a way to change the name of that attachment.
Does anyone know?
The problem is probably this:
var htmlBody = message.Body.Replace("{CID:LOGO}", String.Format("cid:{0}", inline.ContentId));
AlternateView avHtml = AlternateView.CreateAlternateViewFromString(htmlBody, null, MediaTypeNames.Text.Html);
// ...
objMailMsg.AlternateViews.Add(avHtml);
objMailMsg.Body = htmlBody;
You are setting the HTML body text as 2 different body parts. If you create the avHtml part, you shouldn't also need to set objMailMsg.Body = htmlBody.
When MailKit later converts the System.Net.Mail.MailMessage into a MimeMessage, it probably ends up with 2 duplicate parts, one that gets used as the actual HTML body and one that gets added as an attachment w/o a name (the receiving client likely assigns this part a random name which is what you are seeing).
Alternatively, you could remove the logic that creates a System.Net.Mail.MailMessage completely and just construct a MimeMessage and avoid potential issues in conversion.
var bodyBuilder = new BodyBuilder ();
var logo = bodyBuilder.LinkedResources.Add (System.Web.Hosting.HostingEnvironment.MapPath($"~/Images/logo.png"));
var htmlBody = message.Body.Replace("{CID:LOGO}", String.Format("cid:{0}", logo.ContentId));
bodyBuilder.HtmlBody = htmlBody;
Properties.Settings.Default.Reload();
string fromEmail = Properties.Settings.Default.FromMail;
string fromName = Properties.Settings.Default.FromName;
string smtpPassword = Properties.Settings.Default.PwdSmtp;
var mime = new MimeMessage ();
mime.From.Add (new MailboxAddress (fromName, fromEmail));
mime.To.Add (MailboxAddress.Parse (message.Destination));
mime.Subject = message.Subject;
mime.Body = bodyBuilder.ToMessageBody ();
HeaderId[] headersToSign = new HeaderId[] { HeaderId.From, HeaderId.Subject, HeaderId.Date };
string domain = "example.cl";
string selector = "default";
DkimSigner signer = new DkimSigner(#"C:\inetpub\dkim.pem", domain, selector)
{
HeaderCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Relaxed,
BodyCanonicalizationAlgorithm = DkimCanonicalizationAlgorithm.Simple,
AgentOrUserIdentifier = "#contact.example.cl",
QueryMethod = "dns/txt",
};
mime.Prepare(EncodingConstraint.EightBit);
signer.Sign(mime, headersToSign);

failed to send the file by Email

I am created a report viewer using rdlc report system. but the problem is got, when I send this file by email then I found an error. My program is something like that:-
at first, I created a reporting process, which shows my "Order" database's all information. that information shows me as one file system on my desktop when I run my application. this file, I want to send by email. but when I trying to send this, I found many errors.
Here is my code:-
public async Task<IActionResult> CheckOut(Order11 anOrder)
{
//other code
//report process
string mimetype = "";
int extension = 1;
var path = $"{this._webHostEnvironment.WebRootPath}\\Reports\\Report2.rdlc";
Dictionary<string, string> parameters = new Dictionary<string, string>();
var products = _db.Order.ToList();
LocalReport localReport = new LocalReport(path);
localReport.AddDataSource("DataSet1", products);
var result = localReport.Execute(RenderType.Pdf, extension, parameters, mimetype);
var s= File(result.MainStream, "application/pdf");
//report process end
//Email Sender start
var email = anOrder.Email;
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Ghatia Bazar",
"pri#gmail.com"));
message.To.Add(new MailboxAddress("pritom", email));
message.Subject = "Order Details";
message.Body = new TextPart("plain")
{
Text = "Hi,Thanks For Order.",
};
//add attach
MemoryStream memoryStream = new MemoryStream();
BodyBuilder bb = new BodyBuilder();
using (var wc = new WebClient())
{
bb.Attachments.Add("s",
wc.DownloadData("path"));
}
message.Body = bb.ToMessageBody();
//end attach
using (var client = new SmtpClient())
{
client.Connect("smtp.gmail.com", 587, false);
client.Authenticate("pri#gmail.com",
"MyPassword");
client.Send(message);
client.Disconnect(true);
}
//Email sender end
//other code
I also use bb.Attachments.Add("s", result.MainStream); instead of bb.Attachments.Add("s", wc.DownloadData("path")); when I use this, then I found an unexpected email. In this email's file, I found a lot of code. so now bb.Attachments.Add("s", wc.DownloadData("path")); I am using this process to attach a file. but here I found a different error.
Here is my output:-
How I will solve this problem.How I send my created file by email. I am still a beginner, please help.
From the code it looks like you are using AspNetCore.Reporting library for generating reports from RDLC files.
Code of this library is available on GitHub at https://github.com/amh1979/AspNetCore.Reporting
LocalReport class from this library has Execute method which return an instance of ReportResult class.
Code of both these classes is located at https://github.com/amh1979/AspNetCore.Reporting/blob/master/AspNetCore.Reporting/LocalReport.cs
ReportResult class has a Property MainStream which represents the content of the report as Byte Array.
Now, attachment to MimeMessage via BodyBuilder support various inputs for file contents such as Stream, byte[] etc.
With this knowledge, I think you can directly use ReportResult.MainStream to attach file to the BodyBuilder.
You can change your code as following to make it working.
var path = $"{this._webHostEnvironment.WebRootPath}\\Reports\\Report2.rdlc";
Dictionary<string, string> parameters = new Dictionary<string, string>();
var products = _db.Order.ToList();
LocalReport localReport = new LocalReport(path);
localReport.AddDataSource("DataSet1", products);
//Following line of code returns an instance of ReportResult class
var result = localReport.Execute(RenderType.Pdf, extension, parameters, mimetype);
var email = anOrder.Email;
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Ghatia Bazar", "pri#gmail.com"));
message.To.Add(new MailboxAddress("pritom", email));
message.Subject = "Order Details";
message.Body = new TextPart("plain")
{
Text = "Hi,Thanks For Order.",
};
var bb = new BodyBuilder();
// Following line will attach the report as "MyFile.pdf".
// You can use filename of your choice.
bb.Attachments.Add("Myfile.pdf", result.MainStream);
message.Body = bb.ToMessageBody();
using (var client = new SmtpClient())
{
client.Connect("smtp.gmail.com", 587, false);
client.Authenticate("pri#gmail.com", "MyPassword");
client.Send(message);
client.Disconnect(true);
}
I hope this will help you resolve your issue.

How attach mail template in .NET core

I am trying to attach the mail template in Mail Kit I am using .NET Core
here is my code
//From Address
string FromAddress = "info#gorollo.com";
string FromAdressTitle = "Gorollo";
//To Address
string ToAddress = email;
string Subject = subject;
string BodyContent = message;
var body = new BodyBuilder();
var mimeMessage = new MimeMessage();
mimeMessage.From.Add(new MailboxAddress
(FromAdressTitle,
FromAddress
));
mimeMessage.To.Add(new MailboxAddress
(
ToAddress
));
mimeMessage.Subject = Subject;
using (var client = new SmtpClient())
{
client.Connect("smtp.mailgun.org", 587, false);
client.Authenticate(
"info#gorollo.com",
"password"
);
await client.SendAsync(mimeMessage);
await client.DisconnectAsync(true);
}
i saw many examples but not able to find the exact solution
so please anyone help me to sort out the problem
I have to attach Signup template in my mail here.
You're almost here. You can use the BodyBuilder to add text or HTML to the body. Either use the TextBody or HtmlBody property to set text or HTML respectively. Use the ToMessageBody() method to create a MimeEntity instance which you can use as the mail body.
Example:
var message = new MimeMessage();
var bodyBuilder = new BodyBuilder();
bodyBuilder.HtmlBody = "<h1>Hello, World!</h1>";
message.Body = bodyBuilder.ToMessageBody();

How to put an image file into a MemoryStream and attach it into an Email

I encrypted an image,
Now I need to read that image, decrypt and attach it into an email.
For first step I try to put an image file and attach it into an Email,
but when i receive email, the attached image is corrupted !
I try many different ways, but without success.
(I created windows application project just for test, Eventually I need to use solution in MVC Web Application project)
private void btnSend_Click(object sender, EventArgs e)
{
var filePath = "D:\\3.jpg"; // path to none encrypted image file
var ms = new MemoryStream(File.ReadAllBytes(filePath));
// Create attachment
var attach = new Attachment(ms, new ContentType(MediaTypeNames.Image.Jpeg));
attach.ContentDisposition.FileName = "sample.jpg";
// Send Email
IMailSender mailSender = new MailSender();
var isSuccess = mailSender.Send(
"sample email title",
"sample#gmail.com",
"sample subject",
"sample body",
new Attachment[] { attach });
MessageBox.Show(isSuccess ? "Email sent successfully" : mailSender.ErrorMessage);
}
using (MailMessage Message = new MailMessage())
{
Message.From = new MailAddress("from#mail.com");
Message.Subject = "My Subject";
Message.Body = "My Body";
Message.To.Add(new MailAddress("to#mail.com"));
//Attach more file
foreach (var item in Attachment)
{
MemoryStream ms = new MemoryStream(File.ReadAllBytes(filePath));
Attachment Data = new Attachment(ms, "FileName");
ContentDisposition Disposition = Data.ContentDisposition;
Disposition.CreationDate = DateTime.UtcNow.AddHours(-5);
Disposition.ModificationDate = DateTime.UtcNow.AddHours(-5);
Disposition.ReadDate = DateTime.UtcNow.AddHours(-5);
Data.ContentType = new ContentType(MediaTypeNames.Application.Pdf);
Message.Attachments.Add(Data);
}
SmtpClient smtp = new SmtpClient("SmtpAddress", "SmtpPort");
smtp.Credentials = new NetworkCredential("SmtpUser", "SmtpPassword");
await smtp.SendMailAsync(Message);
}
I hope this helps

Categories