attach a pdf in an email using SelectPdf .NET without saving PDF - c#

I am using SelectPdf to convert a HTML to PDF and sending the PDF in an email without saving it and putting into a MemoryStream, but the email is never sent
If I create an Email without attaching the PDF is always sent.
Here my code:
public void SendEmail(string htmlBody, string email, string emailBody, string subject)
{
PdfDocument doc = null;
try
{
//Reading the html and converting it to Pdf
HtmlToPdf pdf = new HtmlToPdf();
doc = pdf.ConvertHtmlString(htmlBodyReservaPasajeros);
var streamPdf = new MemoryStream(doc.Save());
//creating the message
message.From = new MailAddress(ConfigurationManager.AppSettings[url + "Email"]);
message.To.Add(new MailAddress(email));
message.Subject = subject;
message.Body = HtmlBody;
message.IsBodyHtml = true;
if (doc != null)
{
message.Attachments.Add(new Attachment(streamPdf , "Prueba.pdf", "application/pdf"));
}
//Sending the email
...
//Closing
streamPdf.Close();
doc.Close();
}
catch (Exception e)
{
}
}
UPDATE
I had two problems:
First: gmail recognized the email as span, but...
Second:Even so I had to write doc.DetachStream() since the pdf was corrupted.
This function detach the object memoryStream from PdfDocument and set it free.
in the end the code is the next:
public void SendEmail(string htmlBody, string email, string emailBody, string subject)
{
PdfDocument doc = null;
try
{
//Reading the html and converting it to Pdf
HtmlToPdf pdf = new HtmlToPdf();
doc = pdf.ConvertHtmlString(htmlBodyReservaPasajeros);
var streamPdf = new MemoryStream(doc.Save());
**doc.DetachStream();**
//creating the message
message.From = new MailAddress(ConfigurationManager.AppSettings[url + "Email"]);
message.To.Add(new MailAddress(email));
message.Subject = subject;
message.Body = HtmlBody;
message.IsBodyHtml = true;
if (doc != null)
{
message.Attachments.Add(new Attachment(streamPdf , "Prueba.pdf", "application/pdf"));
}
//Sending the email
...
//Closing
streamPdf.Close();
doc.Close();
}
catch (Exception e)
{
}
}

This Code worked for me.. !
public void SendEmail(string htmlBody, string email, string emailBody, string subject)
{
try
{
//Reading the html and converting it to Pdf
HtmlToPdf pdf = new HtmlToPdf();
PdfDocument doc = pdf.ConvertHtmlString(htmlBodyReservaPasajeros);
using (MemoryStream memoryStream = new MemoryStream())
{
doc.Save(memoryStream);
byte[] bytes = memoryStream.ToArray();
memoryStream.Close();
MailMessage message= new MailMessage();
message.From = new MailAddress(
ConfigurationManager.AppSettings[url + "Email"]
);
message.To.Add(new MailAddress(email));
message.Subject = subject;
message.Body = htmlBody;
message.IsBodyHtml = true;
message.Attachments.Add(new Attachment(
new MemoryStream(bytes),
"Prueba.pdf"
));
//Sending the email
. . .
}
doc.Close();
}
catch (Exception e)
{
// handle Exception
. . .
}
}

Check to see of the generated memory stream has the current position at the beginning. You might need to set something like this:
streamPdf.Position = 0;

Related

"noname" attachment shown when email sent has image

HELP! So i have this issue wherein theres a "noname" attachment when sending emails with pictures as seen below
Now, i want this to remove since it is not part of my emailer.
heres is my code below
public static bool SendEmailNotification(List<string> toList, List<string> ccList, string subject, string body)
{
bool isSent = true;
try
{
var mail = new MailMessage();
var smtpClient = new SmtpClient(Constants.SMTP.SMTPClient);
var alternateView = AlternateView.CreateAlternateViewFromString(body, null, Constants.SMTP.Format);
mail.From = new MailAddress(Constants.SMTP.EmailAddress);
if (toList != null && toList.Any())
{
foreach (var email in toList)
{
mail.To.Add(email);
}
if (ccList != null && ccList.Any())
{
foreach (var email in ccList)
{
mail.CC.Add(email);
}
}
mail.Subject = subject;
mail.IsBodyHtml = true;
mail.AlternateViews.Add(alternateView);
smtpClient.Credentials = new NetworkCredential(Constants.SMTP.EmailAddress,
Constants.SMTP.EmailPassword, Constants.SMTP.Email);
smtpClient.Send(mail);
}
else
{
isSent = false;
}
}
catch
{
isSent = false;
}
return isSent;
}
The attachment is actually your image payload in binary. It's set to "noname". Reason being is certain parameters aren't set properly. In this case, to do it properly refer to https://brutaldev.com/post/sending-html-e-mail-with-embedded-images-(the-correct-way)
if( attachementFile!=null)
{
Attachment attachment = new Attachment(attachementFile, MediaTypeNames.Application.Octet);
ContentDisposition disposition = attachment.ContentDisposition;
disposition.CreationDate = File.GetCreationTime(attachementFile);
disposition.ModificationDate = File.GetLastWriteTime(attachementFile);
disposition.ReadDate = File.GetLastAccessTime(attachementFile);
disposition.FileName = Path.GetFileName(attachementFile);
disposition.Size = new FileInfo(attachementFile).Length;
disposition.DispositionType = DispositionTypeNames.Attachment;
return attachment;
}
Here's the code from the link in #kendolew's answer with an example on how to properly include an attachment:
public static void SendMessageWithEmbeddedImages()
{
string htmlMessage = #"<html>
<body>
<img src='cid:EmbeddedContent_1' />
</body>
</html>";
SmtpClient client = new SmtpClient("mail.server.com");
MailMessage msg = new MailMessage("noreply#deventerprise.net",
"someone#deventerprise.net");
// Create the HTML view
AlternateView htmlView = AlternateView.CreateAlternateViewFromString(
htmlMessage,
Encoding.UTF8,
MediaTypeNames.Text.Html);
// Create a plain text message for client that don't support HTML
AlternateView plainView = AlternateView.CreateAlternateViewFromString(
Regex.Replace(htmlMessage,
"<[^>]+?>",
string.Empty),
Encoding.UTF8,
MediaTypeNames.Text.Plain);
string mediaType = MediaTypeNames.Image.Jpeg;
LinkedResource img = new LinkedResource(#"C:\Images\MyImage.jpg", mediaType);
// Make sure you set all these values!!!
img.ContentId = "EmbeddedContent_1";
img.ContentType.MediaType = mediaType;
img.TransferEncoding = TransferEncoding.Base64;
img.ContentType.Name = img.ContentId;
img.ContentLink = new Uri("cid:" + img.ContentId);
htmlView.LinkedResources.Add(img);
//////////////////////////////////////////////////////////////
msg.AlternateViews.Add(plainView);
msg.AlternateViews.Add(htmlView);
msg.IsBodyHtml = true;
msg.Subject = "Some subject";
client.Send(msg);
}

Email sending with attachment issue

I am trying to send an email message to different users (with an attachment). The email is being sent, but only one user receives the attachment (image file). Other recipients receive something like empty picture, or picture with name and zero bytes.
I don't really understand what is going wrong. Here is code that I used for sending emails:
public void SendWithFile(string recipientName, string body, string subject = null, HttpPostedFileBase emailFile = null)
{
using (var msg = new MailMessage())
{
msg.To.Add(recipientName);
msg.From = new MailAddress(ConfigurationManager.AppSettings["MailServerSenderAdress"]);
msg.Subject = subject;
msg.Body = body;
msg.SubjectEncoding = Encoding.UTF8;
msg.BodyEncoding = Encoding.UTF8;
msg.IsBodyHtml = true;
msg.Priority = MailPriority.Normal;
using (Attachment data = new Attachment(emailFile.InputStream, Path.GetFileName(emailFile.FileName), emailFile.ContentType))
{
msg.Attachments.Add(data);
using (var client = new SmtpClient())
{
//client configs
try
{
client.Send(msg);
}
catch (Exception ex)
{
throw ex;
}
}
}
}
}
and here is where I call the send email method:
foreach (var recipent in notesRecipients)
{
if (!string.IsNullOrEmpty(userEmail))
{
if (emailFile != null)
emailService.SendWithFile(userEmail, message, null, emailFile);
}
}
You have to seek the stream from the beginning like below before you send the attachment:
emailFile.InputStream.Position = 0;
For more info you can refer to this question here: link

Writing list of strings into Text file adding as attachment to the mail using c#

I am using below code to send an mail with the text file as a attachment and the contents of text file like this "License ADD LOGJz+RC-cVecSpK5-57AOrUlA-6aD3n5Fy-ejFGFIIa-XPU"
public static bool sendMailFromToCCSubMsgAttachment(string fromName, string fromAdd, string toline, string subj, string htmlmsg, string cc, string strAttachment)
{
SmtpClient smtpClient = new SmtpClient(ConfigurationSettings.AppSettings["MAIL_SERVER"], Int32.Parse(ConfigurationSettings.AppSettings["SERVER_PORT"]));
MailMessage mail = new MailMessage();
if (!string.IsNullOrEmpty(strAttachment))
{
ContentType ct = new ContentType();
ct.MediaType = MediaTypeNames.Text.Plain;
Attachment attachFile = Attachment.CreateAttachmentFromString(strAttachment, ct);
mail.Attachments.Add(attachFile);
}
.........
.........
..........
}
Here We are passing above content in "strAttachment" variable to this method
now i am looking to pass list of strings as contents to that text file and the content format like this below..
License ADD 2N674h5A-cVc9XiCG-N0TChPo3-mRVmOtUm-GYup9evK-3d4
License ADD VljH169B-cVe22hrW-U/HMICqW-1aeB5pJE-YpZIOThd-eBc
License ADD FIsc70dC-cVeVN9Ed-J833n4q4-vyMgnOXM-HjsMKrhT-qy0
License ADD LOGJz+RC-cVecSpK5-57AOrUlA-6aD3n5Fy-ejFGFIIa-XPU
How can i add these list of strings as contents to the text file using above code snippet ..
Would any one please help on this ..
Many thanks in advance....
Change input parameter to List<string> and inside method create a string variable to hold Those string separated by Newline, write these to your attachment file.
Like this
public static bool sendMailFromToCCSubMsgAttachment(string fromName, string fromAdd, string toline, string subj, string htmlmsg, string cc, List<string> strAttachment)
{
SmtpClient smtpClient = new SmtpClient(ConfigurationSettings.AppSettings["MAIL_SERVER"], Int32.Parse(ConfigurationSettings.AppSettings["SERVER_PORT"]));
MailMessage mail = new MailMessage();
string strAttachmentboyd = string.Join(Environment.NewLine, strAttachment);
// your other code
}
This is the code I use for attaching a file into an email.
public static void sendMailWithAttachment(string strAttachment)
{
//insert the licence into a memorystream.
//Note not using the 'using' statement with the MemoryStream and StreamWriter.
//If you do you will get a 'cannot access a closed stream' error when attaching the stream into the email
MemoryStream stream = new MemoryStream();
StreamWriter writer = new StreamWriter(stream);
writer.Write(strAttachment);
writer.Flush();
stream.Position = 0;
//start the mail sending
using (SmtpClient client = new SmtpClient())
using (MailMessage oMail = new MailMessage())
{
//mail config settings
client.Port = 25;
client.Host = "localhost";
client.Timeout = 30000;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("userName", "passWord");
//mail content stuff
oMail.From = new MailAddress("fake#false.nl", "yourName");
oMail.To.Add(new MailAddress("fake#false.nl"));
oMail.Subject = "Your Licence";
oMail.IsBodyHtml = true;
oMail.Body = "<html><head></head><body> Hello </body></html>";
//insert the text file as attatchment from the stream
if (!string.IsNullOrEmpty(strAttachment))
{
oMail.Attachments.Add(new Attachment(stream, "Licence.txt", "text/plain"));
}
//send the mail
client.Send(oMail);
}
//dispose the stream and writer containing the license
writer.Dispose();
stream.Dispose();
}

Attach file from internet to mail without saving it in disk in asp.net

I've written a mail sending code for asp.net. it is working fine. I can attach files that are saved on disk. Now I want to attach a file that is on the internet. I can download the file and save it somewhere on disk and attach the file. but I don't want to save the file on disk. I just need to download the file in memory and attach it to my mail. need help to do that.
here is my code for sending email
public void SendMail(string To, string Subject, string Body)
{
MailMessage mail = new MailMessage();
mail.From = new MailAddress("noreply#xyz.com", "xyz");
mail.To.Add(new MailAddress(To));
mail.Subject = Subject;
mail.Body = Body;
mail.IsBodyHtml = true;
using (SmtpClient smtpClient = new SmtpClient())
{
try
{
smtpClient.Send(mail);
}
catch (Exception ex)
{
throw ex;
}
}
}
I want some thing like this
public void SendMail(string To, string Subject, string Body, URI onlineFileURI)
{
MailMessage mail = new MailMessage();
mail.From = new MailAddress("noreply#xyz.com", "xyz");
mail.To.Add(new MailAddress(To));
mail.Subject = Subject;
mail.Body = Body;
mail.IsBodyHtml = true;
//Create the attachment from URL
var attach = [Attachemnt from URL]
mail.Attachments.Add(attach)
using (SmtpClient smtpClient = new SmtpClient())
{
try
{
smtpClient.Send(mail);
}
catch (Exception ex)
{
throw ex;
}
}
}
How I can download the file in memory and attach it?
This is how I ended up doing it based of previous posts:
var url = "myurl.com/filename.jpg"
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
using (HttpWebResponse HttpWResp = (HttpWebResponse)req.GetResponse())
using (Stream responseStream = HttpWResp.GetResponseStream())
using (MemoryStream ms = new MemoryStream())
{
responseStream.CopyTo(ms);
ms.Seek(0, SeekOrigin.Begin);
Attachment attachment = new Attachment(ms, filename, MediaTypeNames.Image.Jpeg);
message.Attachments.Add(attachment);
_smtpClient.Send(message);
}
You can do it by converting page into Stream/byte array and send it
Here is the code
string strReportUser = "RSUserName";
string strReportUserPW = "MySecretPassword";
string strReportUserDomain = "DomainName";
string sTargetURL = "http://SqlServer/ReportServer?" +
"/MyReportFolder/Report1&rs:Command=Render&rs:format=PDF&ReportParam=" +
ParamValue;
HttpWebRequest req =
(HttpWebRequest)WebRequest.Create( sTargetURL );
req.PreAuthenticate = true;
req.Credentials = new System.Net.NetworkCredential(
strReportUser,
strReportUserPW,
strReportUserDomain );
HttpWebResponse HttpWResp = (HttpWebResponse)req.GetResponse();
Stream fStream = HttpWResp.GetResponseStream();
HttpWResp.Close();
//Now turn around and send this as the response..
ReadFullyAndSend( fStream );
ReadFullyAnd send method. NB: the SendAsync call so your not waiting for the server to send the email completely before you are brining the user back out of the land of nod.
public static void ReadFullyAndSend( Stream input )
{
using ( MemoryStream ms = new MemoryStream() )
{
input.CopyTo( ms );
MailMessage message = new MailMessage("from#foo.com", "too#foo.com");
Attachment attachment = new Attachment(ms, "my attachment",, "application/vnd.ms-excel");
message.Attachments.Add(attachment);
message.Body = "This is an async test.";
SmtpClient smtp = new SmtpClient("localhost");
smtp.Credentials = new NetworkCredential("foo", "bar");
smtp.SendAsync(message, null);
}
}
courtesy:Get file to send as attachment from byte array

Send Uploaded File as attachment

I am trying to get an uploaded file to be sent as an attachment in my ashx file. Here is the code I am using:
HttpPostedFile fileupload = context.Request.Files[0];
//filename w/o the path
string file = Path.GetFileName(fileupload.FileName);
MailMessage message = new MailMessage();
//*****useless stuff********
message.To.Add("abc#xxx.com");
message.Subject = "test";
message.From = new MailAddress("test#aaa.com");
message.IsBodyHtml = true;
message.Body = "testing";
//*****useless stuff********
//Fault line
message.Attachments.Add(new Attachment(file, MediaTypeNames.Application.Octet))
//Send mail
SmtpClient smtp = new System.Net.Mail.SmtpClient("xxxx", 25);
smtp.UseDefaultCredentials = false;
smtp.Credentials = new NetworkCredential("xxx", "xxxx");
smtp.Send(message);
I am able to send the email without the attachment.
Do I need to save the file first and then add to attachment?
You do NOT need to, nor should you, save attachments to the server unnecessarily. ASP Snippets has an article on how to do it in ASP.NET WebForms.
Doing it in C# MVC is even nicer:
public IEnumerable<HttpPostedFileBase> UploadedFiles { get; set; }
var mailMessage = new MailMessage();
// ... To, Subject, Body, etc
foreach (var file in UploadedFiles)
{
if (file != null && file.ContentLength > 0)
{
try
{
string fileName = Path.GetFileName(file.FileName);
var attachment = new Attachment(file.InputStream, fileName);
mailMessage.Attachments.Add(attachment);
}
catch(Exception) { }
}
}
Following in the footsteps of Serj Sagan, here's a handler using webforms, but with <input type="file" name="upload_your_file" /> instead of the <asp:FileUpload> control:
HttpPostedFile file = Request.Files["upload_your_file"];
if (file != null && file.ContentLength > 0)
{
string fileName = Path.GetFileName(file.FileName);
var attachment = new Attachment(file.InputStream, fileName);
mailMessage.Attachments.Add(attachment);
}
This is useful if you don't need (or can't add) a runat="server" on your form tag.
You can do like this:
private void btnSend_Click(object sender,EventArgs e)
{
MailMessage myMail = new MailMessage();
myMail.To = this.txtTo.Text;
myMail.From = "<" + this.txtFromEmail.Text + ">" + this.txtFromName.Text;
myMail.Subject = this.txtSubject.Text;
myMail.BodyFormat = MailFormat.Html;
myMail.Body = this.txtDescription.Text.Replace("\n","<br>");
//*** Files 1 ***//
if(this.fiUpload1.HasFile)
{
this.fiUpload1.SaveAs(Server.MapPath("MyAttach/"+fiUpload1.FileName));
myMail.Attachments.Add(new MailAttachment(Server.MapPath("MyAttach/"+fiUpload1.FileName)));
}
//*** Files 2 ***//
if(this.fiUpload2.HasFile)
{
this.fiUpload2.SaveAs(Server.MapPath("MyAttach/"+fiUpload2.FileName));
myMail.Attachments.Add(new MailAttachment(Server.MapPath("MyAttach/"+fiUpload2.FileName)));
}
SmtpMail.Send(myMail);
myMail = null;
this.pnlForm.Visible = false;
this.lblText.Text = "Mail Sending.";
}
FileName is the name of the file on the client, not on the server. You will need to use SaveAs or the InputStream to get any content into the attachment.
Here is a link to the MSDN documentation.

Categories

Resources