I am new to Notes.
I am trying to send a mail from my application using Lotus Notes with an attachment,mail goes properly and attachment also goes but the problem is with the body content,the body looses its format and comes in a straight line
i expect as follows
Dear Sir,
please check the attachment.
Regards,
NewConcept Infotech Pvt.Ltd.,
but it comes like this
Dear Sir,please check the attachment.Regards,NewConcept Infotech Pvt.Ltd.,
i tried everything googled a lot but no use.
this is my code
public bool Email(string dbDirectory, string DataBase_Name, string Initialize_Pwd, string From, string To, string CC, string Bcc, string Subject, string body, string FileName, string LogFilePath)
{
bool msg = false;
dynamic EMailReplyTo = ConfigurationSettings.AppSettings["EMailReplyTo"];
NotesSession objNotesSession = new NotesSession();
NotesDatabase ndb = null;
NotesDocument ndoc = null;
NotesDbDirectory ndbD = null;
NotesStream LNStream;
NotesMIMEEntity LNBody;
object objAttach;
try
{
////--------------------Lotus Notes Connectivity-------------------------///
List<string> lstOutPutEmail = new List<string>();
lstOutPutEmail.Add(DataBase_Name);
lstOutPutEmail.Add(Initialize_Pwd);
objNotesSession.Initialize(lstOutPutEmail[1].ToString());
//// objNotesSession object Initialized
ndbD = objNotesSession.GetDbDirectory(dbDirectory);
ndb = objNotesSession.GetDatabase(dbDirectory, DataBase_Name, false);
//If the database is not already open then open it.
if (!ndb.IsOpen)
{
ndb.Open();
}
if (ndb != null)
{
ndoc = ndb.CreateDocument();
LNStream = objNotesSession.CreateStream();
LNBody = ndoc.CreateMIMEEntity();
// ndoc.ReplaceItemValue("SendBy", From);
ndoc.ReplaceItemValue("Form", "Memo");
ndoc.ReplaceItemValue("From", From);
ndoc.ReplaceItemValue("Principal", From);
ndoc.ReplaceItemValue("SendTo", To.Split(','));
if (CC != null)
{
if (CC != "")
{
ndoc.ReplaceItemValue("CopyTo", CC.Split(','));
}
}
if (Bcc != null)
{
if (Bcc != "")
{
ndoc.ReplaceItemValue("BlindCopyTo", Bcc.Split(','));
}
}
ndoc.ReplaceItemValue("Subject", Subject);
//
NotesRichTextItem objMailRTF = ndoc.CreateRichTextItem("Body");
ndoc.ReplaceItemValue("Body", body);
ndoc.SaveMessageOnSend = true;
if (FileName != "")
{
objAttach = objMailRTF.EmbedObject(Domino.EMBED_TYPE.EMBED_ATTACHMENT, "", FileName, "Attachment");
}
ndoc.Send(false);
ndbD = null;
objNotesSession = null;
ndb = null;
ndoc = null;
gl.runLogfile("Mail Send Successfuly To : " + To, LogFilePath);
}
msg = true;
}
catch (Exception ex)
{
Console.WriteLine("Error On sending Mail To : " + To);
gl.runLogfile("Error On sending Mail To : " + To, LogFilePath);
gl.runLogfile(ex.Message, LogFilePath);
msg = false;
}
finally
{
}
return msg;
}
Use RichTextItem's method AddNewLine() do add new lines to your Body field
NotesRichTextItem objMailRTF = ndoc.CreateRichTextItem("Body");
objMailRTF.AppendText("Dear Sir,");
objMailRTF.AddNewLine(1);
objMailRTF.AppendText("please check the attachment.");
objMailRTF.AddNewLine(2);
...
Delete the code line ndoc.ReplaceItemValue("Body", body); as it won't work otherwise.
0. MIME
If you are using MIME then you don't need to create the Body field. But you need to use <br> instead of newline characters.
//Remove this from your code:
//NotesRichTextItem objMailRTF = ndoc.CreateRichTextItem("Body");
//ndoc.ReplaceItemValue("Body", body);
objNotesSession.ConvertMIME = false;
LNStream.WriteText(body.Replace(Environment.NewLine, "<br>"));
LNBody.SetContentFromText(stream, "text/plain;charset=UTF-8", 1728);
ndoc.SaveMessageOnSend = true;
if (FileName != "")
{
//objAttach = objMailRTF.EmbedObject(Domino.EMBED_TYPE.EMBED_ATTACHMENT, "", FileName, "Attachment");
var child = LNBody.CreateChildEntity();
var header = child.CreateHeader("Content-Disposition");
header.SetHeaderValAndParams(string.Format("attachment; filename=\"{0}\""), Path.GetFileName(FileName));
LNStream = objNotesSession.CreateStream();
LNStream.Open(FileName, "binary");
child.SetContentFromBytes(LNStream, "application/octet-stream", 1730);
child.EncodeContent(1727);
ndoc.CloseMIMEEntities(True, "Body");
}
1. No MIME
If you don't want to use MIME then you must use AppendText method instead of ReplaceItemValue method:
NotesRichTextItem objMailRTF = ndoc.CreateRichTextItem("Body");
//ndoc.ReplaceItemValue("Body", body);
objMailRTF.AppendText(body);
ndoc.SaveMessageOnSend = true;
if (FileName != "")
{
objMailRTF = ndoc.CreateRichTextItem("Attachment");
objAttach = objMailRTF.EmbedObject(Domino.EMBED_TYPE.EMBED_ATTACHMENT, "", FileName, "Attachment");
}
In your ndoc.body, you have to code the newlines as "chr$(13)chr$(10)". In java (char)13(char)10 or \r\n.
You need to replace in the String body, you get in parameter, all occurence of newline (probably '\n' but look how it is coded in the String) to (char)13(char)10.
try:
body = body.replaceAll("\n", "\r\n");
ndoc.ReplaceItemValue("Body", body);
try will \\ if it doesn't work with 1 \ only.
Related
I have an email template, and in the template, I am replacing some fields passed.
But when I send the mail, the fields being replaced are empty.
On the point of returning the mailtext, when I verify, the fields are properly populated.
I'll be glad if i can get help regarding this.
Please see a snapshot
`
public static string transfer;
public static string airtime;
public static string bills;
public async static Task<string> GetMail(string userName, Goal goal, GoalEvent action)
{
var assembly = Assembly.GetAssembly(typeof(MailHelper));
string title, introText;
string mailText;
Stream stream;
if (action == GoalEvent.SpendActivate)
{
stream = assembly.GetManifestResourceStream("activate.html");
title = "Activated";
introText = $"You have just activated.";
}
else if (action == GoalEvent.SpendCashout)
{
stream = assembly.GetManifestResourceStream("cashout.html");
title = "SpendCashout";
introText = $"Congratulations! You have just been credited {goal.SpendDuration}";
}
else if (action == GoalEvent.SpendDeactivate)
{
stream = assembly.GetManifestResourceStream("deactivate.html");
title = "SpendDeactivated";
introText = $"You have just deactivated";
}
else if (action == GoalEvent.SpendEdit)
{
stream = assembly.GetManifestResourceStream("edit.html");
title = "Updated";
introText = $"You have just successfully updated the details";
}
else if (action == GoalEvent.SpendTopUp)
{
stream = assembly.GetManifestResourceStream("topup.html");
title = "TopUp Successful";
introText = $"We have successfully added NGN {goal.amountSaved}";
}
else
{
return String.Empty;
}
using (var reader = new StreamReader(stream, Encoding.UTF8))
{
mailText = await reader.ReadToEndAsync();
}
if (goal.OnAirtime) airtime = "Airtime and Data";
if (goal.OnBills) bills = "Bills";
if (goal.OnTransfer) transfer = "Transfer";
return ReplaceKeys(mailText,
("title", title),
("date", DateTime.UtcNow.AddHours(1).ToString("dd MMMM yyyy")),
("userName", userName),
("introText", introText),
("duration", goal.Duration.ToString()),
("percentage", goal.Percentage.ToString()),
("transactionTypes", $"{airtime ?? ""}, {bills ?? ""}, {transfer ?? ""}"),
("amountSaved", goal.amountSaved.ToString()),
("interest", goal.interestAccrued.ToString()),
("total", $"{goal.amountSaved + goal.interestAccrued}")
);
}`
please pardon some typos.
This is how I send my email:
public async System.Threading.Tasks.Task<string> SendInternalEmail(BasicEmailStructureViewModel Structure, List<string> AdditionalVariables, TenantEmailTemplate tenantEmailTemplate, TenantCommunication tenantCommunication, string ReceiverId, string ReceiverEmail, string ReceiverName, string CampaignName)
{
try
{
var client = new SendGridClient(tenantCommunication.SendgridApiKey);
var message = new SendGridMessage();
message.SetFrom(new EmailAddress(tenantCommunication.SendgridPrimarySender, tenantCommunication.SendgridPrimarySenderTag));
message.AddTo(new EmailAddress(ReceiverEmail, $"{ReceiverName}"));
message.Subject = tenantEmailTemplate.Subject;
message.SetTemplateId(tenantEmailTemplate.TemplateId);
List<string> jsonVars = new List<string>();
var subjectString = #$"""subject"":""{tenantEmailTemplate.Subject}""";
jsonVars.Add(subjectString);
foreach (PropertyInfo prop in Structure.GetType().GetProperties())
{
var variableString = #$"""{prop.Name}"":""{prop.GetValue(Structure, null)}""";
}
for (var i = 0; i < AdditionalVariables.Count; i++)
{
jsonVars.Add(AdditionalVariables[i]);
}
var flattenList = "{" + string.Join(",", jsonVars) + "}";
var emailData = Newtonsoft.Json.JsonConvert.DeserializeObject<object>(flattenList);
message.SetTemplateData(emailData);
if (CampaignName != null && CampaignName != "")
{
message.AddCustomArg("CampaignName", CampaignName);
}
var response = await client.SendEmailAsync(message);
if (response.IsSuccessStatusCode == true)
{
return Guid.NewGuid().ToString();
}
else
{
var errorMessage = response.Body.ReadAsStringAsync().Result;
return errorMessage;
}
}
catch(Exception e)
{
if (e != null)
{
return e.Message;
}
}
return "Invalid Email";
}
A typical input to this function will be like this:
var variableString =
#$"""verification_link"":""www.website.com?Key={Input.Key}""";
My email sends normally, however, none of the variables that I have set have been sent through. This is based roughly off the template sample on github: https://github.com/sendgrid/sendgrid-csharp/blob/main/examples/templates/templates.cs
Is there another sample I can use or what is the correct way to send variables dynamically?
I don't think that is the best way to construct the JSON for your dynamic template variables.
Would it be possible for you to build the variables as an object and then serialize them. Like:
var templateData = new {
subject = tenantEmailTemplate.Subjectm
otherVariableName = otherVariable
};
string emailData = JsonConvert.SerializeObject(templateData);
message.SetTemplateData(emailData);
I'm sending emails with asp.net core 2.0 like this
public string EmailServiceSend(string body, string subject = null, string to = null,
string multipleRecipients = null, string attachmentUrl = null, string smtpClient = null,
string userCredential = null, string userPassword = null, string from = null, bool template = false,
string templateRoute = null)
{
try
{
SmtpClient client = new SmtpClient("mysmtpserver");
client.UseDefaultCredentials = false;
client.Credentials = new NetworkCredential("username", "password");
MailMessage mailMessage = new MailMessage();
mailMessage.From = new MailAddress("whoever#me.com");
mailMessage.To.Add("receiver#me.com");
mailMessage.Body = body;
mailMessage.Subject = subject;
client.Send(mailMessage);
}
catch(Exception ex)
{
ex.Message.ToString();
}
return "Email sended"
}
I want to know, how can I create a list of email domains to block and send an error message. For example I want to block this domains:
0-mail.com
0815.ru
0clickemail.com
0wnd.net
and then send a response into my return statement for example:
if(listofblockmails == true){
return "You can't add this email domain, change it please"
}
How can I achieve that? Regards
Try using Linq:
Lets say you have this List:
List<string> listofblockmails = new List<string>();
listofblockmails.Add("0-mail.com");
listofblockmails.Add("0815.ru");
listofblockmails.Add("0clickemail.com");
listofblockmails.Add("0wnd.net");
You can do as below:
if (listofblockmails.Contains("emailToBeChecked.com"))
{
//return "You can't add this email domain, change it please";
}
else
{
//send
//return "Email sended";
}
And let Garbage collector do the disposal.
You can simply parse the email address and get the domain part, and compare againist a list of bad domains. If the domain is present in your bad domain list, return messge.
You can create a method like this.
private bool IsGoodDomain(string email)
{
if (string.IsNullOrEmpty(email))
return false;
var badDomains = new List<string>
{
"0815.ru",
"0wnd.net"
};
var r = email.Split('#');
if (!r.Any()) return false;
var domainName = r.Last();
return !badDomains.Contains(domainName, StringComparer.InvariantCultureIgnoreCase);
}
and call this method in your other method
if(IsGoodDomain(someEmailAddressVariable))
{
//contnue sending
}
else
{
// return the error message
}
Referring to the answer mentioned in the post:
Reading Outlook Mail with C#
This code works well for a single account, but the issue with the current code is that it reads the email of the default id which was set as the first one in the outlook app.
For example, if "abcxyz#outlook.com" is set as the first account and "decxyz#outlook.com" is set as the second one, then it reads the inbox of only the first id, i.e., "abcxyz#outlook.com". I tried doing some modifications in the code but it did not work. Below is my code:
public static void OutLookMailStart(string EmailID, string password)
{
Microsoft.Office.Interop.Outlook.Application app = null;
Microsoft.Office.Interop.Outlook._NameSpace ns = null;
Microsoft.Office.Interop.Outlook.PostItem item = null;
Microsoft.Office.Interop.Outlook.MAPIFolder inboxFolder = null;
Microsoft.Office.Interop.Outlook.MAPIFolder subFolder = null;
Microsoft.Office.Interop.Outlook.MailItem mailItem = null;
try
{
app = new Microsoft.Office.Interop.Outlook.Application();
ns = app.GetNamespace("MAPI");
ns.Logon(EmailID, password, false, true);
inboxFolder = ns.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderInbox);
foreach (Object mail in inboxFolder.Items)
{
if ((mail as MailItem) != null && (mail as MailItem).UnRead == true)
{
// Email Subject
string Subject = (mail as MailItem).Subject.ToString();
if (Subject.Contains(FileDomain))
{
// Email Body
var ReplyText = ExtractReply(((mail as MailItem).Body.ToString()), FromTrimName);
}
// (mail as MailItem).UnRead = false;
(mail as MailItem).Save();
}
}
}
catch (System.Exception ex)
{
throw ex;
}
finally
{
ns.Logoff();
inboxFolder = null;
subFolder = null;
mailItem = null;
app = null;
}}
Any sort of help will be appreciated.
public static void OutLookMailStart(string EmailID, string password)
{
Microsoft.Office.Interop.Outlook.Application app = null;
Microsoft.Office.Interop.Outlook._NameSpace ns = null;
Microsoft.Office.Interop.Outlook.PostItem item = null;
Microsoft.Office.Interop.Outlook.MAPIFolder inboxFolder = null;
Microsoft.Office.Interop.Outlook.MAPIFolder subFolder = null;
Microsoft.Office.Interop.Outlook.MailItem mailItem = null;
try
{
app = new Microsoft.Office.Interop.Outlook.Application();
ns = app.GetNamespace("MAPI");
ns.Logon(EmailID, password, true, true);
inboxFolder = ns.Folders[EmailID].Folders[2];
foreach (Microsoft.Office.Interop.Outlook.MailItem mailItemm in inboxFolder.Items)
{
if (mailItemm.UnRead) // I only process the mail if unread
{
// Email Subject
Console.WriteLine("Subject : {0}", mailItemm.Subject);
string Subject = mailItemm.Subject;
if (!string.IsNullOrEmpty(Subject) && !string.IsNullOrWhiteSpace(Subject))
{
if (Subject.Contains(FileDomain))
{
var SenderName = mailItemm.Sender.Name;
//Email Body
Console.WriteLine("Accounts: {0}", mailItemm.Body);
// Read All Attachements
var attachments = (mailItemm as MailItem).Attachments;
if (attachments != null && attachments.Count > 0)
{
for (int i = 1; i <= attachments.Count; i++)
{
attachments[i].SaveAsFile(tempFolderPath + (mailItemm as MailItem).Attachments[i].FileName);
}
}
}
}
}
}
}
catch (System.Exception ex)
{
throw ex;
}
finally
{
ns.Logoff();
inboxFolder = null;
subFolder = null;
mailItem = null;
app = null;
}
}
Using ExchangeService service
public static void Cloud_OutLookMailStart(string EmailID, string password, string StoreFilePath)
{
try
{
LogHelper.LogMessage("<----- Cloud_OutLookMailStart Start ----->");
DistributionReplyEntity ObjDistributionReplyEntity = new DistributionReplyEntity();
ObjDistributionReplyEntity.OutLookEmailID = EmailID;
ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2010_SP1);
service.Credentials = new WebCredentials(EmailID, password);
service.TraceEnabled = true;
service.TraceFlags = TraceFlags.All;
//service.Url = new Uri("https://IP/EWS/Exchange.asmx");
service.AutodiscoverUrl(EmailID, RedirectionUrlValidationCallback);
Microsoft.Exchange.WebServices.Data.Folder inbox = Microsoft.Exchange.WebServices.Data.Folder.Bind(service, WellKnownFolderName.Inbox);
var items = service.FindItems(
//Find Mails from Inbox of the given Mailbox
new FolderId(WellKnownFolderName.Inbox, new Mailbox(EmailID)),
//Filter criterion
// new SearchFilter.SearchFilterCollection(LogicalOperator.And, new SearchFilter[] {
// new SearchFilter.ContainsSubstring(ItemSchema.Subject, ConfigurationManager.AppSettings["ValidEmailIdentifier"].ToString()),
new SearchFilter.IsEqualTo(EmailMessageSchema.IsRead, false),
// }),
//View Size as 15
new ItemView(50));
Console.WriteLine("Email {0}, unread Total Count{1}", EmailID, items.Count());
foreach (Item item in items)
{
EmailMessage email = EmailMessage.Bind(service, new ItemId(item.Id.UniqueId.ToString()));
if (!string.IsNullOrEmpty(email.Subject) && !string.IsNullOrWhiteSpace(email.Subject))
{
var subject = email.Subject.ToString();
String[] arr = subject.Split(' ');
String firstWord = arr[0];
if (firstWord != "Undeliverable:")
{
//PROCESS EMAIL MESSAGE
Console.WriteLine("Subject :{0}", email.Subject);
// TO
if (email.ToRecipients.Count > 0)
{
var propertySet = new PropertySet(ItemSchema.UniqueBody);
EmailMessage email2 = EmailMessage.Bind(service, email.Id, propertySet);
EmailMessage str = (EmailMessage)email2;
string str1 = str.UniqueBody.Text.ToString();
var EmailBody = ExtractReply(str1, "");
// string ReceiverEmail = email.ReceivedBy != null?email.ReceivedBy.Address:"" ;
// Email Body
// var subjectEmail = ExtractReply(email.Body.ToString(), email.ReceivedBy.Address);
Console.WriteLine("Body {0}", EmailBody.ToString()); // Body
ObjDistributionReplyEntity.EmailBody = EmailBody;
string maltipleTo = string.Empty;
foreach (var toemailid in email.ToRecipients)
{
if (string.IsNullOrEmpty(maltipleTo))
{
maltipleTo = toemailid.Address.ToString();
}
else
{
maltipleTo += ";" + toemailid.Address.ToString();
}
}
Console.WriteLine("TO {0}", maltipleTo.ToString()); // TO
ObjDistributionReplyEntity.ReplyTO = maltipleTo.ToString();
}
// CC
if (email.CcRecipients.Count > 0)
{
string maltipleCC = string.Empty;
foreach (var ccemailid in email.CcRecipients)
{
if (string.IsNullOrEmpty(maltipleCC))
{
maltipleCC = ccemailid.Address.ToString();
}
else
{
maltipleCC += ";" + ccemailid.Address.ToString();
}
}
Console.WriteLine("CC {0}", maltipleCC.ToString());
ObjDistributionReplyEntity.ReplyCC = maltipleCC.ToString();
}
// Form
if (email.Sender.Address != "")
{
ObjDistributionReplyEntity.ReplyForm = email.Sender.Address;
}
Console.WriteLine("Subject {0}", email.Subject.ToString()); // Subject
ObjDistributionReplyEntity.Subject = email.Subject.ToString();
ObjDistributionReplyEntity.TransactionsID = 0;
ObjDistributionReplyEntity.IsProjectRelated = 0;
string Subject = email.Subject;
ObjDistributionReplyEntity.ReceivedTime = email.DateTimeReceived;
var getSharePointFileUrl = GetAttachmentsFromEmail(service, item.Id, StoreFilePath, ObjDistributionReplyEntity.TransactionsID);
email.IsRead = true;
email.Update(ConflictResolutionMode.AlwaysOverwrite);
}
}
}
LogHelper.LogMessage("<----- Cloud_OutLookMailStart Start ----->");
}
catch (Exception ex)
{
LogHelper.LogError("OutLookMailStart -> Cloud_OutLookMailStart Exception");
LogHelper.LogError("Exception Message :" + ex.Message);
if (ex.InnerException != null)
{
LogHelper.LogError("Exception InnerException :" + ex.InnerException);
}
LogHelper.LogError("Exception StackTrace :" + ex.StackTrace);
LogHelper.LogError("OutLookMailStart -> Cloud_OutLookMailStart Exception");
}
}
public static string GetAttachmentsFromEmail(ExchangeService service, ItemId itemId, string StoreFilePath, Int64 TransactionsID)
{
try
{
LogHelper.LogMessage("<----- GetAttachmentsFromEmail Start ----->");
// Bind to an existing message item and retrieve the attachments collection.
// This method results in an GetItem call to EWS.
EmailMessage message = EmailMessage.Bind(service, itemId, new PropertySet(ItemSchema.Attachments));
List<ResponseMessage> ObjResponseMessage = new List<ResponseMessage>();
// Iterate through the attachments collection and load each attachment.
foreach (Attachment attachment in message.Attachments)
{
if (attachment is FileAttachment)
{
FileAttachment fileAttachment = attachment as FileAttachment;
// Load the attachment into a file.
// This call results in a GetAttachment call to EWS.
fileAttachment.Load(StoreFilePath + fileAttachment.Name);
string FileName = fileAttachment.Name;
LogHelper.LogMessage("OutLookMailStart In attachments File Name :" + FileName );
Console.WriteLine("File attachment name: " + fileAttachment.Name);
}
else // Attachment is an item attachment.
{
ItemAttachment itemAttachment = attachment as ItemAttachment;
// Load attachment into memory and write out the subject.
// This does not save the file like it does with a file attachment.
// This call results in a GetAttachment call to EWS.
itemAttachment.Load();
Console.WriteLine("Item attachment name: " + itemAttachment.Name);
}
}
}
catch (Exception ex)
{
LogHelper.LogError("OutLookMailStart -> GetAttachmentsFromEmail Exception");
LogHelper.LogError("Exception Message :" + ex.Message);
if (ex.InnerException != null)
{
LogHelper.LogError("Exception InnerException :" + ex.InnerException);
}
LogHelper.LogError("Exception StackTrace :" + ex.StackTrace);
LogHelper.LogError("OutLookMailStart -> GetAttachmentsFromEmail Exception"); ;
}
LogHelper.LogMessage("<----- GetAttachmentsFromEmail End ----->");
}
I'm trying to send HTML e-mails with attached Excel filenames. It all worked well until I neded to send messages whose attachment name contains accented letters :-( Every workaround I've tried failed miserably.
Original code:
var attachment = new Attachment(
new MemoryStream(excelFileContents),
"simplefilename.xls");
This one works fine.
However if I replace "simplefilename.xls" by "échec.xls", the attachment is garbaged (name and contents).
I tried these, to no avail:
var attachment = new Attachment(
new MemoryStream(excelFileContents),
new System.Net.Mime.ContentType("application/vnd.ms-excel"));
attachment.Name = "échec.xls";
The last one is even worse: SmtpClient.Send() throws an exception, complaining about the é in the filename:
var attachment = new Attachment(
new MemoryStream(excelFileContents),
new System.Net.Mime.ContentType("application/vnd.ms-excel"));
attachment.ContentDisposition.FileName = "échec.xls";
I've been banging my head on this one for way too long. Any lights warmly welcomed!
I finally came across an answer that worked.
http://social.msdn.microsoft.com/Forums/en-US/dotnetframeworkde/thread/b6c764f7-4697-4394-b45f-128a24306d55
The content is in German except for the post by Marcel Roma. I put in his code into my application. I was able to send out pdf with accents and we were to see the attachment instead of garbage.
So here it is:
public class AttachmentHelper
{
public static System.Net.Mail.Attachment CreateAttachment(string attachmentFile, string displayName, TransferEncoding transferEncoding)
{
System.Net.Mail.Attachment attachment = new System.Net.Mail.Attachment(attachmentFile);
attachment.TransferEncoding = transferEncoding;
string tranferEncodingMarker = String.Empty;
string encodingMarker = String.Empty;
int maxChunkLength = 0;
switch (transferEncoding)
{
case TransferEncoding.Base64:
tranferEncodingMarker = "B";
encodingMarker = "UTF-8";
maxChunkLength = 30;
break;
case TransferEncoding.QuotedPrintable:
tranferEncodingMarker = "Q";
encodingMarker = "ISO-8859-1";
maxChunkLength = 76;
break;
default:
throw (new ArgumentException(String.Format("The specified TransferEncoding is not supported: {0}", transferEncoding, "transferEncoding")));
}
attachment.NameEncoding = Encoding.GetEncoding(encodingMarker);
string encodingtoken = String.Format("=?{0}?{1}?", encodingMarker, tranferEncodingMarker);
string softbreak = "?=";
string encodedAttachmentName = encodingtoken;
if (attachment.TransferEncoding == TransferEncoding.QuotedPrintable)
encodedAttachmentName = HttpUtility.UrlEncode(displayName, Encoding.Default).Replace("+", " ").Replace("%", "=");
else
encodedAttachmentName = System.Convert.ToBase64String(Encoding.UTF8.GetBytes(displayName));
encodedAttachmentName = SplitEncodedAttachmentName(encodingtoken, softbreak, maxChunkLength, encodedAttachmentName);
attachment.Name = encodedAttachmentName;
return attachment;
}
private static string SplitEncodedAttachmentName(string encodingtoken, string softbreak, int maxChunkLength, string encoded)
{
int splitLength = maxChunkLength - encodingtoken.Length - (softbreak.Length * 2);
var parts = SplitByLength(encoded, splitLength);
string encodedAttachmentName = encodingtoken;
foreach (var part in parts)
encodedAttachmentName += part + softbreak + encodingtoken;
encodedAttachmentName = encodedAttachmentName.Remove(encodedAttachmentName.Length - encodingtoken.Length, encodingtoken.Length);
return encodedAttachmentName;
}
private static IEnumerable<string> SplitByLength(string stringToSplit, int length)
{
while (stringToSplit.Length > length)
{
yield return stringToSplit.Substring(0, length);
stringToSplit = stringToSplit.Substring(length);
}
if (stringToSplit.Length > 0) yield return stringToSplit;
}
}
Use it in the following way:
static void Main(string[] args)
{
string smtpServer = String.Empty;
string userName = String.Empty;
string password = String.Empty;
string attachmentFilePath = String.Empty;
string displayName = String.Empty;
System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient(smtpServer);
client.Credentials = new System.Net.NetworkCredential(userName, password);
var msg = new System.Net.Mail.MailMessage(fromAddress, toAddress, "Subject", "Body");
System.Net.Mail.Attachment attachment =
AttachmentHelper.CreateAttachment(attachmentFilePath, displayName, TransferEncoding.Base64);
msg.Attachments.Add(attachment);
client.Send(msg);
}
You need to use the Quoted-Printable format for the attachment name:
C#: Class for decoding Quoted-Printable encoding?
http://www.codeproject.com/KB/security/TextCoDec.aspx