Programatically attaching document(s) to an email in asp.net - c#

I am generating an email via codebehind in C# in my asp.net application using the line below:
ClientScript.RegisterStartupScript(this.GetType(), "FormLoading", "window.open('mailto:AccountsPayable#xyzCorp.com?subject=Invoice for ABC Corp - " + ddlJobCode.SelectedItem.Text + " - Supporting Documentation', 'email');", true);
Is it possible to include an attachment programatically as well (if the user points to the attachment document via a browse button) ?

No I don't think so... the mailto functionality is passed off by the browser to the default client. You have no other mechanism of talking to the client or even knowing if the mailto was even successful.
If you want to add an attachment you will most likely have to send the email on behalf of them and do it server side.
Edit: To do it server side you would need to post the page so that the Browse button pulls down the file server side and then you would need to construct the email and send it out via your own smtp server. Here is a quick code example, you will probably need to adapt it to work with your specific case:
In your server side OnClick handler:
protected void btnSendEmail_Click(object sender, EventArgs e)
{
// this will get the file from your asp:FileUpload control (browse button)
HttpPostedFile file = (HttpPostedFile)(fuAttachment.PostedFile);
if ((file != null) && (file.ContentLength > 0))
{
// You should probably check file size and extension types and whatever
// other validation here as well
byte[] uploadedFile = new byte[file.ContentLength];
file.InputStream.Read(uploadedFile, 0, file.ContentLength);
// Save the file locally
int lastSlash = file.FileName.LastIndexOf('\\') + 1;
string fileName = file.FileName.Substring(lastSlash,
file.FileName.Length - lastSlash);
string localSaveLocation = yourLocalPathToSaveFile + fileName;
System.IO.File.WriteAllBytes(localSaveLocation, uploadedFile);
try
{
// Create and send the email
MailMessage msg = new MailMessage();
msg.To = "someone#somewhere.com";
msg.From = "somebody#somebody.com";
msg.Subject = "Attachment Test";
msg.Body = "Test Attachment";
msg.Attachments.Add(new MailAttachment(localSaveLocation));
// Don't forget you have to setup your SMTP settings
SmtpMail.Send(msg);
}
finally
{
// make sure to clean up the file that was uploaded
System.IO.File.Delete(localSaveLocation);
}
}
}

Not using the mailto method no, since it doesn't have any options for attachments.
You could have the user fill out a form which will create and send the email on the server side allowing you to add attachments and much more (in my opinion this is also more professional than mailto links which don't really support people using webmail services) However, this would then send the email through your server's email service, rather than the one the client would use.

Related

Is there any way to send HTML e-mail with embedded image in UWP

I am working on a uwp app to send html email with embedded image. I was using EASendMail nuget pakage and it was fine after some time my app shows error:
A connection attempt failed because the connected party did not
properly respond after a period of time, or established connection
failed because connected host has failed to respond. (Exception from
HRESULT: 0x8007274c)
I think the trial period has expired what should I do?
using EASendMailRT;
https://www.emailarchitect.net/easendmail/kb/csharp.aspx?cat=8
I can't find any alternative
try
{
string ToAddress = MailSendPage.toAddressTxtBox;
string Subject = MailSendPage.subjectTxtBox;
SmtpMail oMail = new SmtpMail("TryIt");
oMail.From = new MailAddress(username);
if(!String.IsNullOrEmpty(ToAddress)&& !String.IsNullOrEmpty(Subject))
{
oMail.To.Add(new MailAddress(ToAddress));
oMail.Subject = Subject;
EASendMailRT.SmtpClient oSmtp = new EASendMailRT.SmtpClient();
SmtpServer oServer = new SmtpServer(host);
oServer.User = username;
oServer.Password = password;
oServer.Port = port;
if (IsStackPanalHasImg() == true)
{
StorageFolder localFolder = ApplicationData.Current.LocalFolder;
string[] files = Directory.GetFiles(localFolder.Path + #"\ProjectImages");
foreach (string eachfile in files)
{
foreach (string name in covertToHtml.ControlName)
{
string pattern = string.Format("{0}.jpeg", name);
if (Regex.IsMatch(eachfile, pattern))
{
Attachment oAttachment = await oMail.AddAttachmentAsync(eachfile);
oAttachment.ContentID = name;
}
}
}
}
await oSmtp.SendMailAsync(oServer, oMail);
popUpMsgs.popup(" The Mail has been sent");
}
}
catch (Exception ep)
{
popUpMsgs.popup(String.Format("Failed to send email with the following error: {0}", ep.Message));
}
The built-in e-mail API only support sending plain text e-mail messages as Docs state:
This method only sends plain text messages. You can't set the body of the message to the HTML format.
What you can do is attach images to the e-mail:
EmailMessage mail = new EmailMessage();
mail.Sender = new EmailRecipient("test#example.com");
mail.To.Add(new EmailRecipient("someone#example.com"));
mail.Subject = "Hello";
mail.Body = "World";
var file = await StorageFile.GetFileFromApplicationUriAsync(
new Uri("ms-appx:///Assets/StoreLogo.png"));
mail.Attachments.Add(new EmailAttachment(file.Name, file));
await Windows.ApplicationModel.Email.EmailManager.ShowComposeNewEmailAsync(mail);
In addition, sending attachments works well only in case of the built-in UWP Outlook Mail client. Classic Outlook will most likely ignore the attachments altogether.
If you need to embed the image, you will need to use a e-mail service. I can recommend SendGrid or MailGun. Both have C# APIs which work like a breeze. They are also free for limited number of e-mails.
There are several ways you can embed the images in a HTML e-mail message.
The oldest is using CID (Content ID) which you were using in your question.
Second option is using Base64 encoding. You first turn your image into a Base64 string. There are many tutorials on this, for example in this blogpost. Then you can just embed the image in the src of your <img> tag:
<img src="data:image/jpeg;base64, YOURIMAGEINBASE64"/>
Finally you can embed an image which is hosted somewhere. This scales the best if you need to send the e-mail to many recipients, but of course requires actually hosting the image somewhere. Of the three methods it is also supported in most clients.
All three approaches are described in detail in this post.

Sparkpost C# API add attachments to templates

I've been going thumbing through the documentation and searching the internet to find documenation on how to add attachments to created templates. I'm using darrencauthon's CSharp-Sparkpost to handle the API calls. So far what I have is not working. Does anyone have a working solution (possible?) or a better solution for C#? I'm not opposed to using a different library. This is the link to CSharp-Sparkpost
Here's what I've got so far:
var t = new Transmission();
t.Content.From.Email = "from#thisperson.com";
t.Content.TemplateId = "my-template-email";
new Recipient
{
Address = new Address { Email = recipient }
}
.Apply(t.Recipients.Add);
new Attachment
{
Data = //CSVDATA,
Name = "Table.csv",
Type = "text/csv"
}.Apply(t.Content.Attachments.Add);
var client = new SparkPost.Client(Util.GetPassword("sparkpostapikey"));
client.Transmissions.Send(t).Wait();
I've verified that I can send this attachment without a template and also verified that I can send this template without the attachment. So... the Email is getting sent; however, the content received is only the template and substitution data. No attachment with the template email.
Using Darren's library, and combining the requirements for my project, this is the solution I've come up with. I'm just making an additional API call to grab the template Html so I can build the transmission without having to send the template_id. Still using the CSharp-Sparkpost library to make all of the calls. I modified Darren's example SendInline program as such:
static async Task ExecuteEmailer()
{
var settings = ConfigurationManager.AppSettings;
var fromAddr = settings["fromaddr"];
var toAddr = settings["toaddr"];
var trans = new Transmission();
var to = new Recipient
{
Address = new Address
{
Email = toAddr
},
SubstitutionData = new Dictionary<string, object>
{
{"firstName", "Stranger"}
}
};
trans.Recipients.Add(to);
trans.SubstitutionData["firstName"] = "Sir or Madam";
trans.Content.From.Email = fromAddr;
trans.Content.Subject = "SparkPost sending attachment using template";
trans.Content.Text = "Greetings {{firstName or 'recipient'}}\nHello from C# land.";
//Add attachments to transmission object
trans.Content.Attachments.Add(new Attachment()
{
Data = Convert.ToBase64String(System.IO.File.ReadAllBytes(#"C:\PathToFile\ExcelFile.xlsx")),
Name = "ExcelFile.xlsx",
Type = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
});
Console.Write("Sending mail...");
var client = new Client(settings["apikey"]);
client.CustomSettings.SendingMode = SendingModes.Sync;
//retrieve template html and set Content.Html
var templateResponse = await client.Templates.Retrieve("template-email-test");
trans.Content.Html = templateResponse.TemplateContent.Html;
//Send transmission
var response = client.Transmissions.Send(trans);
Console.WriteLine("done");
}
Oh actually, I see now -- you are talking about adding attachments to templates, not attachments.
My answer to that is that back when I developed this library, attachment on templates was not supported by SparkPost itself.
My library allows you to try it, but that's because every template and non-template emails are considered "transmissions." So if you create a transmission, it has the option of adding attachments... but if you send the transmission with a template id, the attachment is ignored.
I could throw an error, or somehow design the API around this limitation, but what if they stopped ignoring the attachment but my library threw an error? I designed the library for flexibility as the SparkPost web API grew, and I didn't want my library to get in the way.
If you want to test if you're sending the attachment right, send your transmission without a transmission id, and instead with a subject and email body. If the email goes through and you get an attachment, then you know it's because of this template/attachment restriction from SparkPost.
NOTE: I'm putting this answer on Stack Overflow, and it's possible that this dated message will no longer be valid in the future.
I'm Darren Cauthon, the primary author of this library.
I have attachment support in my acceptance tests, which are run before each release. The link is below, but the code should be as simple as:
// C#
var attachment = File.Create<Attachment>("testtextfile.txt");
transmission.Content.Attachments.Add(attachment);
https://github.com/darrencauthon/csharp-sparkpost/blob/3a8cb1efbb8c9a0448c71c126ce7f88759867fb0/src/SparkPost.Acceptance/TransmissionSteps.cs#L56

Send code html from page page asp to page aspx for System.Net.Mail

I am trying to send through System.Net.Mail from my server.
To do this I have created a page aspx, that however I don't directly call, in how much my site is realized in classical asp.
To make this self I go to use the object MSXML2.ServerXMLHTTP
file= "http://www.myserver.net/SendGridMail.aspx"
DataToSend="mailTo="& dest &"&Text="& server.HTMLEncode(testo) &"&Object="& server.HTMLEncode(oggetto) &"&bcc="& bcc &"&mailFrom="& from &"&nameFrom=Pippo.Fr"
Set objXmlHttp = Server.CreateObject("MSXML2.ServerXMLHTTP")
objXmlHttp.Open "POST", file, False
objXmlHttp.send DataToSend
In the page ASPX I recall with a request the variables and I pass her to the object MailMessage.
The problems that I have are these.
I don't succeed in sending the methods from the page asp with the object send. I don't receive error but the email not games, I think that it doesn't receive the data.
Set objXmlHttp = Server.CreateObject("MSXML2.ServerXMLHTTP")
objXmlHttp.Open "POST", file, False
file = "http://www.myserver.net/Mail.aspx?mailTo="& dest &"&Text="& server.HTMLEncode(testo) &"&Object="& server.HTMLEncode(oggetto) &"&bcc="& bcc &"&mailFrom="& from &"&nameFrom=Pippo.Fr"
If I send everything through querystring I don't succeed in inserting a text html
code page aspx
string mailTo = Request["mailTo"];
string mailFrom = Request["mailFrom"];
string nameFrom = Request["nameFrom"];
string Object = Request["Object"];
string Text = Request["Text"];
string bcc = Request["bcc"];
MailMessage mailMsg = new MailMessage();
// To
mailMsg.To.Add(new MailAddress(mailTo));
// From
mailMsg.From = new MailAddress(mailFrom, nameFrom);
if (bcc != "")
{
mailMsg.Bcc.Add(bcc);
}
// Subject and multipart/alternative Body
mailMsg.Subject = Object;
mailMsg.Body = Text
Can someone help me?
I want to send some code html in the text and if it is possible to send the data from the page asp on post and not in querystring.
Thanks

Can get only Mail Message body?

I use free .net library to read email and I release: If I want to view body message, all free .net email library download body message and attachments. If attachments have a big size, I wait for a long time. Example: I use AE.NET.Mail to read the lastest email:
var dt = DateTime.Now;
Console.WriteLine(dt.ToLongTimeString());
// Connect to the IMAP server. The 'true' parameter specifies to use SSL
// which is important (for Gmail at least)
var ic = new ImapClient("imap.gmail.com", "yourEmail", "yourPassword",
ImapClient.AuthMethods.Login, 993, true);
// Select a mailbox. Case-insensitive
var mailCount = ic.GetMessageCount();
ic.SelectMailbox("INBOX");
var message = ic.GetMessage(mailCount - 1);
var body = message.Body;
Console.WriteLine(body);
ic.Disconnect();
ic.Dispose();
Console.WriteLine(DateTime.Now.ToLongTimeString());
Console.WriteLine((DateTime.Now - dt).TotalSeconds);
result: 478,6s with attachment size 23mb.
How can I do if I want to view only body message with fastest speed?
I am giving you link please follow it and try another open source mail library It helps you to consume less time . TRY THIS Then put the code as shown below
MailRepository rep = new MailRepository("imap.gmail.com", 993, true, #"username", "password");
foreach (ActiveUp.Net.Mail.Message email in rep.GetUnreadMails("Inbox"))
{
System.Web.HttpContext.Current.Response.Write(string.Format("<p>{0}: {1}</p><p>{2}</p>", email.From, email.Subject, email.BodyHtml.Text));
}

Permission issues when trying to send email via SMTP from ASP.NET page

I have done this before without any issue but now I don't know what's wrong. I have a web page with a button for email which I want to send some data to email addresses with.
I asked our web hosting company for server details and the response I got was:
"You can use the following details for mail.
Incoming mail server: mail.ourSite.com Outgoing mail server: mail.ourSite.com
Username and password are the email address and password associated with the email address.
"
I am not sure about the last line but I created a new email address in the web host's control panel.
The code I use is:
// instantiate a new mail definition and load an html
// template into a string which I replace values in
// then the rest of the code below
md.Subject = String.Format("{0} {1} {2}", emailSubject, firstName, lastName);
MailMessage msg = md.CreateMailMessage(emailAddress, replacements, emailBody, new Control());
md.IsBodyHtml = true;
SmtpClient sc = new SmtpClient(emailServer);
sc.Credentials = new NetworkCredential(emailUsername, emailPassword);
try
{
sc.Send(msg);
}
emailServer - mail.ourSite.com (dummy value in this post)
emailUsername - the email address I created in the control panel
emailPassword - the password for the email above
The error I have is that when I send emails to other domains than our own I get
"Bad sequence of commands. The server response was: This mail server requires authentication when attempting to send to a non-local e-mail address. Please check your mail client settings or contact your administrator to verify that the domain or address is defined for this server."
When I email to an address within our host then it works fine.
The support is not very supportive so I am asking here what you might think the problem could be? I find it strange that I use the password for an email address I created, should it really be like that?
I think that you are using the wrong email address for the NetworkCredential. It should be the one for your email account that you got from the one providing emailServer.
Try this ..
msg.UseDefaultCredentials = false;
NetworkCredential MyCredential = new NetworkCredential("Email", "Password");
msg.Credentials = MyCredential;
here is code to send mail..
i hope i will helpful to you..
using System.Web.Mail;
using System;
public class MailSender
{
public static bool SendEmail(
string pGmailEmail,
string pGmailPassword,
string pTo,
string pSubject,
string pBody,
System.Web.Mail.MailFormat pFormat,
string pAttachmentPath)
{
try
{
System.Web.Mail.MailMessage myMail = new System.Web.Mail.MailMessage();
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/smtpserver",
"smtp.gmail.com");
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/smtpserverport",
"465");
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/sendusing",
"2");
//sendusing: cdoSendUsingPort, value 2, for sending the message using
//the network.
//smtpauthenticate: Specifies the mechanism used when authenticating
//to an SMTP
//service over the network. Possible values are:
//- cdoAnonymous, value 0. Do not authenticate.
//- cdoBasic, value 1. Use basic clear-text authentication.
//When using this option you have to provide the user name and password
//through the sendusername and sendpassword fields.
//- cdoNTLM, value 2. The current process security context is used to
// authenticate with the service.
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate","1");
//Use 0 for anonymous
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/sendusername",
pGmailEmail);
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/sendpassword",
pGmailPassword);
myMail.Fields.Add
("http://schemas.microsoft.com/cdo/configuration/smtpusessl",
"true");
myMail.From = pGmailEmail;
myMail.To = pTo;
myMail.Subject = pSubject;
myMail.BodyFormat = pFormat;
myMail.Body = pBody;
if (pAttachmentPath.Trim() != "")
{
MailAttachment MyAttachment =
new MailAttachment(pAttachmentPath);
myMail.Attachments.Add(MyAttachment);
myMail.Priority = System.Web.Mail.MailPriority.High;
}
System.Web.Mail.SmtpMail.SmtpServer = "smtp.gmail.com:465";
System.Web.Mail.SmtpMail.Send(myMail);
return true;
}
catch (Exception ex)
{
throw;
}
}
}

Categories

Resources