Attachment is not going with email - c#

And i am sending mails from below details :
// language -- C#
// import namespace
using System.Web.Mail;
private void SendEmail()
{
const string SERVER = "relay-hosting.secureserver.net";
MailMessage oMail = new System.Web.Mail.MailMessage();
oMail.From = "emailaddress#domainname";
oMail.To = "emailaddress#domainname";
oMail.Subject = "Test email subject";
oMail.BodyFormat = MailFormat.Html; // enumeration
oMail.Priority = MailPriority.High; // enumeration
oMail.Body = "Sent at: " + DateTime.Now;
SmtpMail.SmtpServer = SERVER;
SmtpMail.Send(oMail);
oMail = null; // free up resources
}
Mails are going properly with above details and now i want to add attachment on email.And for that i have added below code :
String sFile = "http://www.demo.com/abc.pdf";
var oAttch = new System.Web.Mail.MailAttachment(sFile);
oMail.Attachments.Add(oAttch);
But it's not adding the attachment in mail.
It's giving error that "URI formats are not supported".

Mail attachment supports only files from the local drive.
If you want to attach a file that is hosted on the web you should download it to your local drive first.
If you have the file in your local drive you can do something like this:
String sFile = "abc.pdf";
var oAttch = new System.Web.Mail.MailAttachment(Server.MapPath(sFile));
oMail.Attachments.Add(oAttch);

You cant use a file from the web. It must be located on your local drive.
Check out MSDN - MailAttachment Constructor (String)

Related

Fetching attachment from given .eml file and using that attachment to other mail

I am working on code in C#,but not going through on thing that is I have saved some .eml file on my disk now I am parsing each eml file and creating a new mail adding the eml file data to the new mail but I am unable to attach the attachments present in the .eml file to the new mail , can anybody please help?
I am using the follwing code but it shows the error ex = {"The process cannot access the file because it is being used by another process.\r\n":null}
foreach (CDO.IBodyPart attach in msg.Attachments)
{
i++;
string filenm = "C:\\mail_automation\\attachments\\xyz" + i +".eml";
if (File.Exists(filenm))
{
string fn = attach.FileName;
attach.SaveToFile("C:\\mail_automation\\attachments\\xyz" + i + ".eml");
Attachment data = new Attachment(filenm);
mailMessage.Attachments.Add(data);
}
else
{
File.Create(filenm);
string fn = attach.FileName;
attach.SaveToFile("C:\\mail_automation\\attachments\\xyz" + i + ".eml");
Attachment data = new Attachment(filenm);
mailMessage.Attachments.Add(data);
}
You have to extract the attachments and save them to disk first, then fetch it again into the new mail.
Code example here
MailMessage message = new MailMessage();
MemoryStream ms = new MemoryStream(); //store the mail into this ms 'memory stream'
ms.Position = 0;
message.Attachments.Add(new Attachment(ms, attachmentName));

How to save file in a folder in windows application

I want to send an attachment in an email, SO for that I want to save the attachment file in a folder first.
So what's happening with my current code is, the mail is going with attachment but my file is not getting saved into the ATTACHMENT folder.
here is the code i tried
for (int i = 0; i < table.Rows.Count; i++)
{
if (1 == 1)
{
string StrPriBody = "This is a test mail for checking notification.";
MailMessage mail = new MailMessage();
mail.Subject = "Daily Holding followup scheduler";
mail.From = new System.Net.Mail.MailAddress("autosupport#powersoft.in");
SmtpClient smtp = new SmtpClient();
smtp.Timeout = 1000000;
smtp.Port = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["Port"]);
smtp.UseDefaultCredentials = true;
smtp.Host = System.Configuration.ConfigurationManager.AppSettings["MailHost"];
smtp.Credentials = new NetworkCredential(mail.From.ToString(), "PS123456");
smtp.EnableSsl = true;
mail.To.Add(new MailAddress("abc#test.com"));
mail.IsBodyHtml = true;
mail.Body = StrPriBody;
DataSet ds = new DataSet();
ds.Tables.Add(table);
ds.Tables[0].TableName = "Post sale follow up entries auto mailer";
SaveFileDialog save = new SaveFileDialog();
save.InitialDirectory = "\\Attachment";
save.RestoreDirectory = true;
ExcelLibrary.DataSetHelper.CreateWorkbook("Employee_Details.xls", ds);
mail.Attachments.Add(new Attachment("Employee_Details.xls"));
smtp.Send(mail);
foreach (Attachment attachments in mail.Attachments)
{
attachments.Dispose();
}
You don't need a SaveFileDialog to do that (and in your code you define it but you are not using it). Just use File.Copy. So, after creating your Workbook here:
ExcelLibrary.DataSetHelper.CreateWorkbook("Employee_Details.xls", ds);
Just add something like:
File.Copy("Employee_Details.xls","\\Attachment\Employee_Details.xls");
1) Why you are using SaveFileDialog? User must choose folder and file name to save to? Then you forgot to "display" dialog, and after user close it - retrieve chosen folder/file name from it and (preferably) use full path (C:\Folder\File...) for CreateWorkbook and new Attachment(...).
2) Are you sure that after call to ExcelLibrary.DataSetHelper.CreateWorkbook this file is actually written to disk with content? May be you need to call some Save() methods? (this is library-specific, read in library docs)
3) Are you sure that after call to ExcelLibrary.DataSetHelper.CreateWorkbook new file is closed/unlocked by writing code? May be you need to Dispose something? (again, check library docs)
4) Are you testing on server (website?) or desktop machine? Check that you can write access to folder where you want to store your file.

How can I get File.Delete() to actually delete my file?

I generate a PDF file, save it on the server:
var bytes = ms.ToArray();
. . .
String fileFullpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), pdfFileName);
. . .
File.WriteAllBytes(fileFullpath, bytes);
...and then save it into a Sharepoint Document Library, and send it as an email attachment to the person who generated the file:
SavePDFToDocumentLibrary(fileFullpath);
String from = GetFromEmailID();
String to = GetUserEmail();
String subjLine = String.Format("The PDF file you generated ({0})", pdfFileName);
String body = String.Format("The Direct Pay PDF file you generated ({0}) is attached.", pdfFileName);
SendEmailWithAttachment(fileFullpath, from, to, subjLine, body);
// Now that it has been put in a Document Library and emailed, delete the file that was saved locally
File.Delete(fileFullpath);
...at which point, I no longer need the file I saved to disk on the server, and so, as shown in the last line above, attempt to delete it.
However, it doesn't work. The now-redundant file is still in the place where it was saved.
Why, and how can I get it to understand that "Delete" really means "delete"?
UPDATE
Here are the methods Scott wanted to see:
// This works; got it from Henry Zucchini's answer at http://stackoverflow.com/questions/468469/how-do-you-upload-a-file-to-a-document-library-in-sharepoint
private void SavePDFToDocumentLibrary(String fullpath)
{
String fileToUpload = fullpath;
String sharePointSite = siteUrl;
String documentLibraryName = "DirectPayPDFForms";
using (SPSite oSite = new SPSite(sharePointSite))
{
using (SPWeb oWeb = oSite.OpenWeb())
{
if (!System.IO.File.Exists(fileToUpload))
throw new FileNotFoundException("File not found.", fileToUpload);
SPFolder doclib = oWeb.Folders[documentLibraryName];
// Prepare to upload
Boolean replaceExistingFiles = true;
String fileName = System.IO.Path.GetFileName(fileToUpload);
FileStream fileStream = File.OpenRead(fileToUpload);
// Upload document
SPFile spfile = doclib.Files.Add(fileName, fileStream, replaceExistingFiles);
// Commit
doclib.Update();
}
}
}
// This is adapted from https://msdn.microsoft.com/en-us/library/system.net.mail.mailmessage(v=vs.90).aspx
public static void SendEmailWithAttachment(string fileToMail, String from, String to, String subj, String body)
{
String server = GetSMTPHostName(); //"468802-DEV-SPWF"; // change this to prod when go live, or programatically assign?
// Specify the file to be attached and sent.
string file = fileToMail;
// Create a message and set up the recipients.
MailMessage message = new MailMessage(
from,
to,
subj,
body);
// Create the file attachment for this e-mail message.
Attachment data = new Attachment(file, MediaTypeNames.Application.Octet);
// Add time stamp information for the file.
ContentDisposition disposition = data.ContentDisposition;
disposition.CreationDate = System.IO.File.GetCreationTime(file);
disposition.ModificationDate = System.IO.File.GetLastWriteTime(file);
disposition.ReadDate = System.IO.File.GetLastAccessTime(file);
// Add the file attachment to this e-mail message.
message.Attachments.Add(data);
//Send the message.
SmtpClient client = new SmtpClient(server);
// Add credentials if the SMTP server requires them.
client.Credentials = CredentialCache.DefaultNetworkCredentials;
try
{
client.Send(message);
}
catch (Exception ex)
{
Console.WriteLine("Exception caught in CreateMessageWithAttachment(): {0}", ex.ToString());
}
// Display the values in the ContentDisposition for the attachment.
// May not need/want this section
ContentDisposition cd = data.ContentDisposition;
Console.WriteLine("Content disposition");
Console.WriteLine(cd.ToString());
Console.WriteLine("File {0}", cd.FileName);
Console.WriteLine("Size {0}", cd.Size);
Console.WriteLine("Creation {0}", cd.CreationDate);
Console.WriteLine("Modification {0}", cd.ModificationDate);
Console.WriteLine("Read {0}", cd.ReadDate);
Console.WriteLine("Inline {0}", cd.Inline);
Console.WriteLine("Parameters: {0}", cd.Parameters.Count);
foreach (DictionaryEntry d in cd.Parameters)
{
Console.WriteLine("{0} = {1}", d.Key, d.Value);
}
// </ May not need/want this section
data.Dispose();
}
UPDATE 2
I see when stepping through it, after adding this test:
if (File.Exists(fileFullpath))
{
File.Delete(fileFullpath);
}
...that there is an exception after all, in the IOException catch block:
The process cannot access the file 'C:\Users\TEMP.SP.018\Desktop\DirectPayDynamic_2015Jul28_19_02_clayshan_0.pdf' because it is being used by another process.
So how is one of the other methods holding onto it? ISTM that SavePDFToDocumentLibrary() is safe, because it uses using blocks.
Is data.Dispose(); in SendEmailWithAttachment() not enough? Do I need to explicitly call close there, or what?
UPDATE 3
I added "message.Dispose();" just prior to "data.Dispose();" in SendEmailWithAttachment(), but it made no difference.
Try disposing the file stream used in SavePDFToDocumentLibrary like so:
using (FileStream fileStream = File.OpenRead(fileToUpload))
{
...
}

File is used by another process exception C#

I have created an application that generates excel files from information in a database. These files are saved on my HDD in a folder.
After that I attach the files and send them via mail. When I generate another batch of files I delete the old files and then create the new ones.
My problem is when I have generated one batch of files and then send them, and I want to generate another batch I cannot delete the one of the old files, because the mailing method is still holding on to one of the excel files.
Here is my code:
public void SendMailedFilesDKLol() {
string[] sentFiles=Directory.GetFiles(some_Folder);
if(sentFiles.Count()>0) {
System.Net.Mail.SmtpClient client=new System.Net.Mail.SmtpClient("ares");
System.Net.Mail.MailMessage msg=new System.Net.Mail.MailMessage();
msg.From=new MailAddress("system#lol.dk");
msg.To.Add(new MailAddress("lmy#lol.dk"));
msg.Subject="IBM PUDO";
msg.Body=
sentFiles.Count()+" attached file(s) has been sent to the customer(s) in question ";
msg.IsBodyHtml=true;
foreach(string file in sentFiles) {
Attachment attachment=new Attachment(file);
msg.Attachments.Add(attachment);
}
client.Send(msg);
}
}
I have tried to dispose the client element but that didn't help.
Can anyone help me with this?
Both System.Net.Mail.MailMessage & System.Net.Mail.SmtpClient are IDisposable classes. You can try the following,
using (System.Net.Mail.SmtpClient client = new System.Net.Mail.SmtpClient("ares"))
{
using (System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage())
{
msg.From = new MailAddress("system#lol.dk");
msg.To.Add(new MailAddress("lmy#lol.dk"));
msg.Subject = "IBM PUDO";
msg.Body = sentFiles.Count() + " attached file(s) has been sent to the customer(s) in question ";
msg.IsBodyHtml = true;
foreach (string file in sentFiles)
{
Attachment attachment = new Attachment(file);
msg.Attachments.Add(attachment);
}
client.Send(msg);
}
}
It sounds like you may not be closing your file stream when generating the excel files or you have them open in excel when trying to email them.
Please can you show your code for generating the excel files.
You need to dispose the Attachment objects.
Example using LINQ:
public void SendMailedFilesDKLol() {
string[] sentFiles=Directory.GetFiles(some_Folder);
if(sentFiles.Count()>0) {
System.Net.Mail.SmtpClient client=new System.Net.Mail.SmtpClient("ares");
System.Net.Mail.MailMessage msg=new System.Net.Mail.MailMessage();
msg.From=new MailAddress("system#lol.dk");
msg.To.Add(new MailAddress("lmy#lol.dk"));
msg.Subject="IBM PUDO";
msg.Body=
sentFiles.Count()+" attached file(s) has been sent to the customer(s) in question ";
msg.IsBodyHtml=true;
var attachments = sentFiles.Select(f => new Attachment(f)).ToList();
attachments.ForEach(a => msg.Attachments.Add(a));
client.Send(msg);
attachments.ForEach(a => a.Dispose());
}
}

delete attachment file

i am using System.Net.Mail for sending mail in asp.net..
how to delete attachment file after it is send as attachment mail..
i tried to use File.Delete method.. but i am getting this error..
the process cannot access the file path\fun.jpg' because it is being used by another process.
thank you
Dispose of the MailMessage when you're done with it.
It still has a lock on the file you've added as an attachment until you've done so.
var filePath = "C:\\path\\to\\file.txt";
var smtpClient = new SmtpClient("mailhost");
using (var message = new MailMessage())
{
message.To.Add("to#domain.com");
message.From = new MailAddress("from#domain.com");
message.Subject = "Test";
message.SubjectEncoding = Encoding.UTF8;
message.Body = "Test " + DateTime.Now;
message.Attachments.Add(new Attachment(filePath));
}
if (File.Exists(filePath)) File.Delete(filePath);
Console.WriteLine(File.Exists(filePath));
Output: False
I would imagine that if you still have something locking the file after disposing the message, that you likely have another lock on the file, but without code, we can't help you.
You can't delete a attached file after sending the mail.Before sending you can delete.
What the error says that, the path you have mentioned is using some other process.
MailMessage Message = new MailMessage();
Message.Subject = "Attachment Test";
Message.Body = "Check out the attachment!";
Message.To.Add("webmaster#15Seconds.com");
Message.From = "someone#somedomain.com";
Message.Attachments.Add(new Attachment(memorystream, "test.txt", MediaTypeNames.Application.Text));
Notice that we created the attachment from the MemoryStream and we got to name the attachment anything we want. The name of the attachment in the second parameter is the name of the file in the email, not the name on the local system hard drive. In fact the attachment never goes to the local hard drive. The third parameter is the Mime type of the attachment, in our case this is text.
Edit: use Dispose() the mail
Extending the MailMessage class is a good way to solve this and reduce the chances of running into this problem again...
class MyMailMessage : MailMessage, IDisposable
{
private List<string> _tempFiles = new List<string>();
public void Attach(string filename)
{
base.Attachments.Add(new Attachment(filename));
this._tempFiles.add(filename);
}
new public void Dispose()
{
base.Dispose();
this._tempFiles.Foreach(x => File.Delete(x));
}
}
... and remember to use with a 'using' construct (which you should be using anyway)...
using(SmtpClient client = GetMySmtpClient())
using(MyMailMessage msd = new MyMailMessage())
{
msg.Attach(filename);
client.send(msg);
}
If your mail have lots Attachments
List<Attachments> lstAtt = new List<Attachments>();
Attachment att = new Attachment(file);
lstAtt.Add(att);
//finally
foreach(var a in lstAtt)
{
a.Dispose();
}
//delete file
You just need to dispose the message object before deleting the file. E.g:
Dim message As New MailMessage
message.From = New MailAddress(fromEmail, fromName)
message.Subject = subject
message.CC.Add(toCCEmail)
message.Bcc.Add(toBCCEmail)
Dim attach As Attachment = New Attachment(attachmentPath)
message.Attachments.Add(attach)
message.IsBodyHtml = True
message.Body = body
mailClient.Send(message)
message.Dispose() 'Add this line to dispose the message!

Categories

Resources