how to send embedded images with MailKit? - c#

I followed this guide to try and embed 2 images on Emails
this is my code written in C# for a console application:
the ExecuteSendMailEx procedure:
public void ExecuteSendMailEx(AccesBase accesBase, string From, string Subjet, bool Format, string EmailLogoHeader, string EmailLogoFooter, string ReplyTo, string ReturnPath, string BodyHtml, string BodyText, string Destinataire, string IdLangage, string CopieCachee, string PJ, string SMTP, string SMTPPORT, string SMTPLOGIN, string SMTPPWD, ref int RTN)
{
try
{
Log.Information("ENVOI_Constructor ExecuteSendMailEx has begun");
var email = new MimeMessage();
email.From.Add(MailboxAddress.Parse(From));
email.To.Add(MailboxAddress.Parse(Destinataire));
email.ReplyTo.Add(MailboxAddress.Parse(ReplyTo));
if (!string.IsNullOrEmpty(CopieCachee))
email.Bcc.Add(MailboxAddress.Parse(CopieCachee));
email.Subject = Subjet;
email.Sender = (MailboxAddress.Parse(SMTPLOGIN));
var currentDirectory = Directory.GetCurrentDirectory();
var parentDirectory = Directory.GetParent(currentDirectory).FullName;
var filesDirectory = parentDirectory + "\\Files";
var builder = new BodyBuilder();
if (EmailLogoHeader != "" && EmailLogoFooter != "")
{
var imageHead = builder.LinkedResources.Add(filesDirectory + "\\" + EmailLogoHeader);
imageHead.ContentId = MimeUtils.GenerateMessageId();
var imageFoot = builder.LinkedResources.Add(filesDirectory + "\\" + EmailLogoFooter);
imageFoot.ContentId = MimeUtils.GenerateMessageId();
builder.HtmlBody = string.Format(#"<img src='cid:{0}'><br>{1}<br><img src='cid:{2} '>", imageHead.ContentId, BodyHtml, imageFoot.ContentId);
}
else if (EmailLogoFooter != "" && EmailLogoHeader == "")
{
var imageFoot = builder.LinkedResources.Add(filesDirectory + "\\" + EmailLogoFooter);
imageFoot.ContentId = MimeUtils.GenerateMessageId();
builder.HtmlBody = string.Format(#"{0}<br><img src='cid={1}'>", BodyHtml, imageFoot.ContentId);
}
else if (EmailLogoHeader != "" && EmailLogoFooter == "")
{
var imageHead = builder.LinkedResources.Add(filesDirectory+"\\" + EmailLogoHeader);
imageHead.ContentId = MimeUtils.GenerateMessageId();
builder.HtmlBody = string.Format(#"<img src='cid:{0}'><br>{1}", imageHead.ContentId, BodyHtml);
}
else
builder.HtmlBody = BodyHtml;
builder.TextBody = BodyText ;
if (Format == false)
{
builder.Attachments.Add(addImage(filesDirectory + EmailLogoHeader));
builder.Attachments.Add(addImage(filesDirectory + EmailLogoFooter));
}
email.Body = Format == false ? new TextPart(TextFormat.Text) { Text = builder.TextBody } : new TextPart(TextFormat.Html){ Text= builder.HtmlBody };
// send email
var smtp = new MailKit.Net.Smtp.SmtpClient();
smtp.Connect(SMTP, Int32.Parse(SMTPPORT), SecureSocketOptions.StartTls);
smtp.Authenticate(SMTPLOGIN, SMTPPWD);
smtp.Send(email);
smtp.Disconnect(true);
}
catch (Exception ex) { Log.Error(ex.Message + " : " + ex.InnerException + " - ENVOI_Constructor: ExecuteSendMailEx Method"); }
}
obviously, my first lines of the code are:
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Globalization;
using System.Linq;
using System.Web;
using TP;
using System.Net;
using System.Net.Mail;
using MimeKit;
using MimeKit.Text;
using MailKit.Net.Smtp;
using MailKit.Security;
using Serilog;
using System.Drawing;
using System.IO;
using MimeKit.Utils;
expected behavior: I tried everything to embed images to Emails sent with MailKit, but they always come out as
all variables contain correct values like SMTP hosting the Exchange server address or SMTPPORT containing the port, every variable is named like its meaning,
the EmailHeaderLogo & EmailFooterLogo contain the pathes like Mail\image.jpg,
I navigated to the parent folder because the files are on the parent folder and inside the path that exist on the variable,
sorry that the code may seem French, I'm not french but where I'm working is a french international company,
if you want any additional information, don't hesitate to ask me,
and thank you

The problem is that you are setting the message body incorrectly.
Replace the following line:
email.Body = Format == false ? new TextPart(TextFormat.Text) { Text = builder.TextBody } : new TextPart(TextFormat.Html){ Text= builder.HtmlBody };
with this:
email.Body = builder.ToMessageBody();
I don't understand Format is supposed to do, but it looks like if Format is false, then you want only plain-text?
If so, you'll want to change your code to the following:
public void ExecuteSendMailEx(AccesBase accesBase, string From, string Subjet, bool Format, string EmailLogoHeader, string EmailLogoFooter, string ReplyTo, string ReturnPath, string BodyHtml, string BodyText, string Destinataire, string IdLangage, string CopieCachee, string PJ, string SMTP, string SMTPPORT, string SMTPLOGIN, string SMTPPWD, ref int RTN)
{
try
{
Log.Information("ENVOI_Constructor ExecuteSendMailEx has begun");
var email = new MimeMessage();
email.From.Add(MailboxAddress.Parse(From));
email.To.Add(MailboxAddress.Parse(Destinataire));
email.ReplyTo.Add(MailboxAddress.Parse(ReplyTo));
if (!string.IsNullOrEmpty(CopieCachee))
email.Bcc.Add(MailboxAddress.Parse(CopieCachee));
email.Subject = Subjet;
email.Sender = (MailboxAddress.Parse(SMTPLOGIN));
var currentDirectory = Directory.GetCurrentDirectory();
var parentDirectory = Directory.GetParent(currentDirectory).FullName;
var filesDirectory = Path.Combine(parentDirectory, "Files");
var builder = new BodyBuilder();
if (Format)
{
// If we have any headers or footers, inject those into the HTML body
if (!string.IsNullOrEmpty(EmailLogoHeader) && !string.IsNullOrEmpty(EmailLogoFooter))
{
var imageHead = builder.LinkedResources.Add(Path.Combine(filesDirectory, EmailLogoHeader));
imageHead.ContentId = MimeUtils.GenerateMessageId();
var imageFoot = builder.LinkedResources.Add(Path.Combine(filesDirectory, EmailLogoFooter));
imageFoot.ContentId = MimeUtils.GenerateMessageId();
builder.HtmlBody = string.Format(#"<img src='cid:{0}'><br>{1}<br><img src='cid:{2} '>", imageHead.ContentId, BodyHtml, imageFoot.ContentId);
}
else if (!string.IsNullOrEmpty(EmailLogoFooter))
{
var imageFoot = builder.LinkedResources.Add(Path.Combine(filesDirectory, EmailLogoFooter));
imageFoot.ContentId = MimeUtils.GenerateMessageId();
builder.HtmlBody = string.Format(#"{0}<br><img src='cid={1}'>", BodyHtml, imageFoot.ContentId);
}
else if (!string.IsNullOrEmpty(EmailLogoHeader))
{
var imageHead = builder.LinkedResources.Add(Path.Combine(filesDirectory, EmailLogoHeader));
imageHead.ContentId = MimeUtils.GenerateMessageId();
builder.HtmlBody = string.Format(#"<img src='cid:{0}'><br>{1}", imageHead.ContentId, BodyHtml);
}
else
{
builder.HtmlBody = BodyHtml;
}
}
else
{
// No HTML body is desired, so just add the header and footer images as attachments instead.
if (!string.IsNullOrEmpty(EmailLogoHeader))
builder.Attachments.Add(Path.Combine(filesDirectory, EmailLogoHeader));
if (!string.IsNullOrEmpty(EmailLogoFooter))
builder.Attachments.Add(Path.Combine(filesDirectory, EmailLogoFooter));
}
builder.TextBody = BodyText;
email.Body = builder.ToMessageBody();
// send email
using (var smtp = new MailKit.Net.Smtp.SmtpClient())
{
smtp.Connect(SMTP, Int32.Parse(SMTPPORT), SecureSocketOptions.StartTls);
smtp.Authenticate(SMTPLOGIN, SMTPPWD);
smtp.Send(email);
smtp.Disconnect(true);
}
}
catch (Exception ex)
{
Log.Error(ex.Message + " : " + ex.InnerException + " - ENVOI_Constructor: ExecuteSendMailEx Method");
}
}
Note: I took the liberty of changing your code to use string.IsNullOrEmpty() instead of doing a direct comparison with "" as well as fixing your code to use Path.Combine(). You should really get into the habit of using Path.Combine(), especially, since it will help make your code portable to non-Windows platforms if you ever want to run your code on .NET Core (where it may run on a Linux or Mac).

Related

SSIS - REST API for Freshdesk

I tried searching something here but nothing seems to fit my need.
I created an SSIS package that runs a report -> Attaches it to an email and send it to a bunch of people, many times (different recipients, different files).
Due to Zapier limitations I can't create a FreshDesk ticket with attachments and that is for me a must to have so I'm exploring FreshDesk API, but I'm no c# developer.
I found some examples online and now I'm trying to fit this code:
FreshSamples C-Sharp Create Ticket with attachment into my existing code, hoping to pass all my variable as ticket fields '
#region VSTA generated code
enum ScriptResults
{
Success = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Success,
Failure = Microsoft.SqlServer.Dts.Runtime.DTSExecResult.Failure
};
#endregion
public void Main()
{
// initialize StreamReader class for text file
StreamReader streamReader = new StreamReader(Dts.Variables["User::MHTMailPath"].Value.ToString());
// Read the StreamReader To End and assign to local variable
string StreamText = streamReader.ReadToEnd();
// assign SSIS variable with value of StreamText local variable.
this.Dts.Variables["User::HTMLMail"].Value = StreamText;
// TODO: Add your code here
MailMessage email = new MailMessage();
if ((Dts.Variables["User::MHTEmail1"].Value.ToString() != null) && (Dts.Variables["User::MHTEmail1"].Value.ToString() != string.Empty))
{
email.To.Add(Dts.Variables["User::MHTEmail1"].Value.ToString());
}
if ((Dts.Variables["User::MHTEmail2"].Value.ToString() != null) && (Dts.Variables["User::MHTEmail2"].Value.ToString() != string.Empty))
{
email.To.Add(Dts.Variables["User::MHTEmail2"].Value.ToString());
}
if ((Dts.Variables["User::MHTEmail3"].Value.ToString() != null) && (Dts.Variables["User::MHTEmail3"].Value.ToString() != string.Empty))
{
email.To.Add(Dts.Variables["User::MHTEmail3"].Value.ToString());
}
if ((Dts.Variables["User::MHTEmail4"].Value.ToString() != null) && (Dts.Variables["User::MHTEmail4"].Value.ToString() != string.Empty))
{
email.To.Add(Dts.Variables["User::MHTEmail4"].Value.ToString());
}
//email.CC.Add(CCAddresses);
email.From = new MailAddress("xxx#xxx.com");
email.Subject = Dts.Variables["User::MHTCd"].Value.ToString() + " - " + Dts.Variables["User::MHTCustomerDS"].Value.ToString() + " R" + Dts.Variables["User::Period"].Value.ToString().Trim().Substring(Dts.Variables["User::Period"].Value.ToString().Trim().Length - 2, 2);
email.IsBodyHtml = true;
email.Body = Dts.Variables["User::HTMLMail"].Value.ToString();
string reportFile = Dts.Variables["User::ReportFile"].Value.ToString();
try
{
//For MHT file. Decode MHTML to HTML and embed in email body
if (Path.GetExtension(reportFile) == ".mht")
{
var decodedHtml = new StringBuilder();
using (var reader = new StreamReader(reportFile))
{
while (!reader.EndOfStream)
{
var line = reader.ReadLine();
if (line != "Content-Transfer-Encoding: base64") continue;
reader.ReadLine();
while ((line = reader.ReadLine()) != String.Empty)
if (line != null)
decodedHtml.Append(
Encoding.UTF8.GetString(
Convert.FromBase64String(line)));
break;
}
}
email.Body = email.Body + Environment.NewLine + decodedHtml.ToString();
email.IsBodyHtml = true;
}
else
{
//Attach the file
Attachment attachmentFile = new Attachment(reportFile);
email.Attachments.Add(attachmentFile);
}
}
catch (Exception e)
{
Dts.Events.FireError(0, "create email message", e.Message, String.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
//System.Diagnostics.Process proc = new System.Diagnostics.Process();
SmtpClient smtpClient = new SmtpClient("smtp.gmail.com", 587);
smtpClient.EnableSsl = true;
smtpClient.Credentials = new System.Net.NetworkCredential("xxx#xxx.com", "xxxxxxx");
System.Diagnostics.Process proc = new System.Diagnostics.Process();
try
{
smtpClient.Send(email);
//email.Attachments.Dispose();
//File.Delete(reportFile);
Dts.TaskResult = (int)ScriptResults.Success;
}
catch (Exception e)
{
Dts.Events.FireError(0, "smtp emailing", e.Message, String.Empty, 0);
Dts.TaskResult = (int)ScriptResults.Failure;
}
finally
{
if (email != null)
{
email.Dispose();
}
if (smtpClient != null)
{
//smtpClient.Dispose();
}
}
Dts.TaskResult = (int)ScriptResults.Success;
}
}
but I'm losing my mind trying to get my reportFile to be correctly "taken" by FreshDesk sample which expects a file on the filesystem. Moreover, I will need to attach more that one file so I was wondering if any good samaritan would point me in the right direction.
Thanks in advance
Ren
It will be okay to call email.Attachments.Add() multiple times to add multiple attachments:
The key part is :
To turn an existing file into an attachment:
Attachment attachmentFile = new Attachment(reportFile);
email.Attachments.Add(attachmentFile);
To turn a string block into an attachment:
using (var stream = new MemoryStream())
using (var writer = new StreamWriter(stream))
{
writer.Write(reportFile);
writer.Flush();
stream.Position = 0;
email.Attachments.Add(new Attachment(stream, "myreport-xyz.txt", "text/plain"));
}

GetFileByServerRelativePath does not work and always returns file not found

I was previously using the GetFileByServerRelativeUrl and it was working fine, but the characters # and % are not supported while they are supposed to be supported with GetFileByServerRelativePath, so I changed the code as per below but now it just doesn't work with any files???
public bool DownloadFile(string filepath, out string Base64EncodedFile, out string errormessage)
{
Base64EncodedFile = string.Empty;
errormessage = string.Empty;
try
{
Uri filename = new Uri(filepath);
string serverrelative = filename.AbsolutePath;
//This old method does not support # or % but works fine
//Microsoft.SharePoint.Client.File file = context.Web.GetFileByServerRelativeUrl(serverrelative);
// >> Replaced with this
ResourcePath filePathDecoded = ResourcePath.FromDecodedUrl(serverrelative);
Microsoft.SharePoint.Client.File file = context.Web.GetFileByServerRelativePath(filePathDecoded);
// << Replaced with this
context.Load(file);
ClientResult<System.IO.Stream> streamResult = file.OpenBinaryStream();
context.ExecuteQuery();
Base64EncodedFile = ConvertToBase64(streamResult.Value);
return true;
}
catch (Exception ex)
{
errormessage = ex.Message;
return false;
}
}
SharepointClient.SharepointClient newupload = new SharepointClient.SharepointClient("https://xxxxxxx.sharepoint.com/sites/xxxxxxxxx/", usernametext.Text, textpassword.Text);
newupload.DownloadFile(Url.Text, out EncodedAbs, out errormessage);
If I use the old GetFileByServerRelativeUrl it works just fine... I tried everything but I cannot seem to get to work the GetFileByServerRelativePath ... I can't understand what I'm doing wrong???
Please help!!!
My test code for your reference.
using (ClientContext ctx = new ClientContext(targetSiteURL))
{
ctx.Credentials = onlineCredentials;
string fileName = "FileWith#%.docx";
var _File = ctx.Web.GetFileByServerRelativePath(ResourcePath.FromDecodedUrl($"/sites/lee/MyDoc/{fileName}"));
ctx.Load(_File);
ctx.ExecuteQuery();
Console.Write(_File.ServerRelativeUrl);
Console.WriteLine();
}

Sending email using Microsoft.Office.Interop.Outlook; with image attatchment [duplicate]

I have the following code:
string imageSrc = "C:\\Documents and Settings\\menonsu\\Desktop\\screenScrapper\\Bitmap1.bmp";
oMsg.HTMLBody = "<HTML><BODY><img src = \" cid:Bitmap1.bmp#embed \"/><br><font size=\"2\" face=\"Courier New\">" + introText + "</font>" + body + "<font size=\"2\" face=\"Courier New\">" + conclText + "</font>" + " </BODY></HTML>";
Microsoft.Office.Interop.Outlook.Attachment attc = oMsg.Attachments.Add(imageSrc, Microsoft.Office.Interop.Outlook.OlAttachmentType.olEmbeddeditem, null, "");
attc.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E", "Bitmap1.bmp#EMBED");
//Send the message.
oMsg.Save();
For some reason the email is just showing an x when i try to run this code...anyone know why?
The following is working code with two ways of achieving this:
using System;
using Outlook = Microsoft.Office.Interop.Outlook;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Method1();
Method2();
}
public static void Method1()
{
Outlook.Application outlookApp = new Outlook.Application();
Outlook.MailItem mailItem = outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
mailItem.Subject = "This is the subject";
mailItem.To = "john#example.com";
string imageSrc = "D:\\Temp\\test.jpg"; // Change path as needed
var attachments = mailItem.Attachments;
var attachment = attachments.Add(imageSrc);
attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x370E001F", "image/jpeg");
attachment.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001F", "myident"); // Image identifier found in the HTML code right after cid. Can be anything.
mailItem.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/id/{00062008-0000-0000-C000-000000000046}/8514000B", true);
// Set body format to HTML
mailItem.BodyFormat = Outlook.OlBodyFormat.olFormatHTML;
string msgHTMLBody = "<html><head></head><body>Hello,<br><br>This is a working example of embedding an image unsing C#:<br><br><img align=\"baseline\" border=\"1\" hspace=\"0\" src=\"cid:myident\" width=\"\" 600=\"\" hold=\" /> \"></img><br><br>Regards,<br>Tarik Hoshan</body></html>";
mailItem.HTMLBody = msgHTMLBody;
mailItem.Send();
}
public static void Method2()
{
// Create the Outlook application.
Outlook.Application outlookApp = new Outlook.Application();
Outlook.MailItem mailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
//Add an attachment.
String attachmentDisplayName = "MyAttachment";
// Attach the file to be embedded
string imageSrc = "D:\\Temp\\test.jpg"; // Change path as needed
Outlook.Attachment oAttach = mailItem.Attachments.Add(imageSrc, Outlook.OlAttachmentType.olByValue, null, attachmentDisplayName);
mailItem.Subject = "Sending an embedded image";
string imageContentid = "someimage.jpg"; // Content ID can be anything. It is referenced in the HTML body
oAttach.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001E", imageContentid);
mailItem.HTMLBody = String.Format(
"<body>Hello,<br><br>This is an example of an embedded image:<br><br><img src=\"cid:{0}\"><br><br>Regards,<br>Tarik</body>",
imageContentid);
// Add recipient
Outlook.Recipient recipient = mailItem.Recipients.Add("john#example.com");
recipient.Resolve();
// Send.
mailItem.Send();
}
}
}
From what I can tell, you are not setting the content id properly. Try to change the code to the following:
attc.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x370E001F", "image/bmp");
attc.PropertyAccessor.SetProperty("http://schemas.microsoft.com/mapi/proptag/0x3712001F", "Bitmap1.bmp#EMBED");
I have done this before a little differently. I embedded images in some emails that I had to send from my web app using an 'alternate view' in the system.net.mail
System.Net.Mail.LinkedResource theContent = new System.Net.Mail.LinkedResource({path to image});
theContent.ContentID = "TheContent";
String altViewString = anEmail.Body.replace("{original imageSource i.e. '../Images/someimage.gif'}","cid:TheContent");
System.Net.Mail.AlternateView altView = System.Net.Mail.AlternateView.CreateAlternateViewFromString(altViewString, Nothing, System.Net.Mime.MediaTypeNames.Text.Html);
altView.LinkedResources.add(theContent);
anEmail.Message.AlternateViews.Add(altView);
Here's a simple solution:
private static void insertPictureAsLink(Outlook.MailItem mail, String imagePath, String URI)
{
mail.BodyFormat = OlBodyFormat.olFormatHTML;
mail.HTMLBody += String.Format("<body></body>", imagePath, URI);
mail.Display(false);
}

StreamWriter stops in the middle of a WriteLine

I have a small application that checks all of the logs in a directory named after domain usernames and generates a results file with each username and the relevant first and surname for that user.
The console is outputting the full list successfully but it seems that the StreamWriter is stopping halfway through an entry.
The number of characters it writes before stopping is consistent - to some extent. If I set the outputstring to include more characters between the two variables filename and the result from FindNameFromUsername then the character count with or without spaces changes so I've ruled that out.
Any ideas as to why the console outputs the line but the streamwriter doesn't?
Code below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.DirectoryServices;
using System.DirectoryServices.AccountManagement;
using System.DirectoryServices.ActiveDirectory;
namespace Filename_Finder
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Please insert the full directory path. All filenames in the root of this folder will be logged to one file.");
string outputFilename = "results.txt";
string userPath = Console.ReadLine();
string domain = "ou=users,dc=domain,dc=local";
try
{
string outputFilepath = userPath + outputFilename;
string[] filepaths = Directory.GetFiles(userPath);
using (StreamWriter file = new StreamWriter(outputFilepath, false))
{
for (int i = 0; i < filepaths.Length; i++)
{
string filepath = filepaths[i];
char split = '.';
string filename = filepath.Remove(0, userPath.Count());
if (filename != outputFilename)
{
int extensionBegins = filename.LastIndexOf(split);
filename = filename.Remove(extensionBegins);
string outputstring = (filename + " -- " + FindNameFromUsername(filename, domain));
Console.WriteLine(outputstring);
file.WriteLine(outputstring);
}
}
Console.ReadLine();
}
}
catch (Exception e) { Console.WriteLine(e); Console.ReadLine(); }
}
public static string FindNameFromUsername(string username, string domainScope)
{
string connectionPrefix = "LDAP://" + domainScope;
DirectoryEntry entry = new DirectoryEntry(connectionPrefix);
DirectorySearcher searcher = new DirectorySearcher(entry);
string filter = "(&(objectClass=user)";
filter += "(|(sAMAccountName=" + username + ")))";
searcher.Filter = filter;
SearchResult result = searcher.FindOne();
string resultValue = string.Empty;
DirectoryEntry obj = result.GetDirectoryEntry();
resultValue = "" + obj.Properties["givenName"].Value + " " + obj.Properties["sn"].Value;
if (resultValue == " ") { resultValue = username; }
entry.Close(); entry.Dispose();
obj.Close(); obj.Dispose();
searcher.Dispose();
return resultValue;
}
}
}
Your Console.ReadLine() will pause the execution and I'm guessing that's where you are checking the content of your file.
However, the file won't be flushed and closed until the StreamWriter is being disposed. That happens at the end of the using block, i.e. after your ReadLine() statement.
Take a look at this question.
You might find useful setting your StreamWriter.AutoFlush property to true in order to get similar behavior to the corresponding Console method, like this:
using (var file = new StreamWriter(outputFilepath, false) { AutoFlush = true })

attached .doc is opening properly in pc but in mobile its not opening properly while sending by smtp in .net

im creating .doc file and sending mail. in pc dowloaded file from
attachment is opening properly but in mobile its not opening
properly. only html tags are displaying in smart phones.can u
tell me how to render this .doc file so that in mobile also attached
file can be displayed ?
attached file is not supporting in smartphones .only html tags are
displaying.
can anyone tell in my code how to use docX library in my code?
protected void btnMail_Click(object sender, EventArgs e)
{
DisplayProgressBar();
Response.Clear();
try
{
if (Session["Projectname"] != null && Session["Projectname"].ToString() != string.Empty)
{
string Projname = Session["Projectname"].ToString();
System.IO.StringWriter stringWrite = new System.IO.StringWriter();
System.Web.UI.HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);
design.RenderControl(htmlWrite);
string strBuilder = stringWrite.ToString();
string strPath = Request.PhysicalApplicationPath + "\\Temp\\WeeklyReport of " + Projname + ".doc";
LblNoteMsg.Text = strPath;
//code changed to send mails
if (File.Exists(strPath))
{
var counter = 1;
strPath = strPath.Replace(".doc", " (" + counter + ").doc");
while (File.Exists(strPath))
{
strPath = strPath.Replace("(" + counter + ").doc", "(" + (counter + 1) + ").doc");
counter++;
}
}
using (var fStream = File.Create(strPath))
{
fStream.Close();
fStream.Dispose();
}
using(StreamWriter sWriter = new StreamWriter(strPath))
{
sWriter.Write(strBuilder);
sWriter.Close();
sWriter.Dispose();
Response.Clear();
}
DateTime input = DateTime.Now;
int delta = DayOfWeek.Monday - input.DayOfWeek;
DateTime dats = DateTime.Now.AddDays(delta);
//this week
DateTime monday = input.AddDays(delta);
string MonDate = monday.ToShortDateString();
DateTime sat = monday.AddDays(5);
string SatDate = sat.ToShortDateString();
StreamReader r = new StreamReader(Server.MapPath("~/WeeklyMail.txt"));
string body = r.ReadToEnd();
MailMessage Msg = new MailMessage();
string MailId = txtMailId.Text;
foreach (string ss in MailId.Split(",".ToCharArray()))
{
if (string.IsNullOrEmpty(ss) == false)
{
Msg.To.Add(new MailAddress(ss));
}
}
Msg.Bcc.Add(new MailAddress("support#sunlightit.com"));
body = body.Replace("<%MonDate%>", MonDate);
body = body.Replace("<%SatDate%>", SatDate);
Msg.Subject = "Weekly status Report of " + Projname + "," + DateTime.Now.ToShortDateString() + "";
Msg.Body = body;
Msg.IsBodyHtml = true;
Msg.Attachments.Add(new Attachment(strPath));
SmtpClient MailServer = new SmtpClient();
try
{
MailServer.Send(Msg);
string reply = (Msg.DeliveryNotificationOptions = System.Net.Mail.DeliveryNotificationOptions.OnSuccess).ToString();
if (reply == "OnSuccess")
{
txtMailId.Text = "";
tblMail.Visible = false;
lblMsg.ForeColor = System.Drawing.Color.Green;
lblMsg.Text = "Mail has send succesfully";
}
else
{
lblMsg.ForeColor = System.Drawing.Color.Red;
lblMsg.Text = "Mail delivery unsuccessfull";
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
if (ex.InnerException != null)
{
Console.WriteLine("InnerException is: {0}", ex.InnerException);
}
}
}
else
{
Response.Redirect("~/Login.aspx");
}
}
catch (Exception)
{
ScriptManager.RegisterClientScriptBlock(Page, typeof(Page), "clentscript", "alert('It is being used by another process.Please Try after sometime ');", true);
}
}
You did not make a proper .doc file. A .doc file is not composed of HTML. Word on your computer does know HTML so it will open the file, but likely the program you're using on the mobile devices will just treat it as a corrupted .doc file.
Instead, you should build a proper Word document. There's plenty of libraries for generating .docx Open Office XML Document (Word 2007) files. Find one that works for you needs, and use it.
Write the file on the server path and pass the link to user make the download:
Example:
http://yourapp.com/files/download/051651203210.doc

Categories

Resources