Currently I just created a program which can send the .xls file, I used google smtp server so I can already sent email with that server in my program. And inside my program, based on my date, I can create .xls file with today date and time. What I want to know is this file will be used to be attachment for the email. How I can do it?
Currently my file name is DateTime.Now.ToString("yyyyMMdd_hhss") + ".xls" so I can create based on today date and time. How I can retrieve the file name to be used as email attachment?
I am assuming you are using the .NET's default Emal api found in the System.Net.Mail namespace.
You can add the file as an attachment to the System.Net.Mail.MailMessage object.
The System.Net.Mail.Attachment class accepts a constructor that can take the stream which you could have used to create the xls file. So, if you create the excel file on the fly, you'll probably already have a reference to the stream where it is written. Then you need to use the code below:
using (Stream myXlsFileStream = new MemoryStream())
{
// assumig you populate the stream like this...
WriteXlsToStream(myXlsFileStream);
myXlsFileStream.Flush();
MailMessage message = new MailMessage();
// configure mail message contents ...
using (Attachment xlsAttachment = new Attachment(
myXlsFileStream,
"FileNameToAppearInEmail.xls",
"application/xls"))
{
message.Attachments.Add(xlsAttachment);
// send the message
}
}
Please, note that the stream must not be closed, and all data should have been written to it. You may need to call myXlsFileStream.Flush() (as in above code) before adding the attachment, in order to ensure that the file is entirely written.
Related
I have the following situation: an Email with another email as attachment. I'm working in C# using Microsoft.Graph library on an Microsoft 365 account.
As far as I know, I can stream and save the parent email with the following code:
Message m; // m is the parent email that I want to save retrieved with an GetAsync() call
var stream = await graphClient.Me.Messages[m.Id].Content.Request().GetAsync();
var filepath = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) + #"\attachments\" + "emailID" + ".eml";
using (FileStream outputFileStream = new FileStream(filepath, FileMode.Create))
{
stream.CopyTo(outputFileStream);
}
But I cannot do the same with the attached email: I cannot get the Content for the inner email. At the moment I can access to the inner email and read the body, in this way:
var attachmentRequest = graphClient.Me.Messages[m.Id].Attachments[attachment.Id].Request().Expand("microsoft.graph.itemattachment/item").GetAsync();
var itemAttachment = (ItemAttachment)attachmentRequest.Result;
var itemMessage = (Message)itemAttachment.Item;
But saving only the Body is not the intended behaviour. I would like to save the object as an .eml file, in order to open it with Microsoft Outlook client.
Any help would be greatly appreciated.
This scenario is outside of the scope of the Graph API and C# SDK itself.
I would suggest to use MimeKit nuget. MimeKit has a class called MimeMessage.
You can create a new MimeMessage and map/set each field from the Microsoft.Graph.Message object.
var itemMessage = (Message)itemAttachment.Item;
MimeMessage has method WriteTo which allows you to write the message to the specified output stream. You can save the message directly to a file.
I'm working with C# on Windows servers for a web application stored on the IIS Server.
I would like to create an eml file from :
an html content (string)
some attachments that are loaded in memory
a string subject
string recipients
string sender
The main problem is that I am not allowed to store files on the host server (not even in a temporary directory or if I delete them after).
I saw many threads explaining how to create an eml file with the help of SmtpClient. But we always need to use a directory to save the file.
Do someone knows a way to do that ? Or to create a directory in memory (which seems undoable) ?
Thanks for everyone who will read me
[EDIT]
Using jstedfast's answer below and the Mime documentation, I could figure a way. Here is a POC in case someone needs it later.
var message = new MimeMessage();
message.From.Add(new MailboxAddress("Joey", "joey#friends.com"));
message.To.Add(new MailboxAddress("Alice", "alice#wonderland.com"));
message.Subject = "How you doin?";
var builder = new BodyBuilder();
// Set the plain-text version of the message text
builder.TextBody = #"Hey Alice,
What are you up to this weekend? Monica is throwing one of her parties on
Saturday and I was hoping you could make it.
Will you be my +1?
-- Joey
";
// We may also want to attach a calendar event for Monica's party...
builder.Attachments.Add("test.pdf", attachmentByteArray);
// Now we just need to set the message body and we're done
message.Body = builder.ToMessageBody();
using (var memory = new MemoryStream())
{
message.WriteTo(memory);
}
Look into using MimeKit.
You can write the MimeMessage objects to any type of stream that you want, including a MemoryStream.
I am trying to embed an Excel file into an Outlook email message. I am setting the attachment type to "OlAttachmentType.olOLE", however when the message is created, the Excel document arrives as an attachment.
Below is my code. It seems pretty straightforward, but it does not work as expected.
var application = new Microsoft.Office.Interop.Outlook.Application();
var message = (MailItem)application.CreateItem(OlItemType.olMailItem);
var path = #"C:\Excel\Workbook.xlsx";
var missing = System.Type.Missing;
message.Attachments.Add(path, OlAttachmentType.olOLE, 1, missing);
message.SaveAs(#"C:\Excel\Workbook.msg", OlSaveAsType.olMSG);
application.Quit();
Outlook Object Model would not let you insert embedded OLE objects - the best you can do is access existing ones. Inserting OLE attachments is non-trivial even on the Extended MAPI level - you will need to create a specially formatted IStorage for the attachment, then populate its data in the format that only the host that will handle it later can understand. You will also need to provide the bitmap with the preview and insert the appropriate placeholder in the RTF body.
I'm using WinForms. I made a simple Image Viewer application using a picturebox to display my images. I made a way to create temporary files. These files are always picture files. When my application is done using the image i want to be able to delete these temporary on FormClosing files located at: C:\Users\taji01\AppData\Local\Temp\8bd93a0dec76473bb82a12488fd350af To do that i cannot simply call File.Delete(C://picture.jpg) because my application is still using them even though there is another picture displaying in my application. So i tried to dispose it but i couldn't figure how how to do that. Should i be using a using statement? Is there a better way to dispose and delete the file or is there a way to make this work?
_fileName = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N"));
File.Copy(imagePath, _fileName);
_stream = new FileStream(_fileName, FileMode.Open, FileAccess.Read, FileOptions.DeleteOnClose);
this._Source = Image.FromStream(_stream);
Error: "The process cannot access the file C:\picture.jpg because it is being used by another process" Exeption thrown: 'System.IO.IO.Exception' in msconrlib.dll (The process cannot access the file 'C:\picture.jpg' because it is being used by another procesas")
You need to Close() your FileStream.
I think a Transaction manager will do what you want. Check out .NET Transactional File Manager. When you rollback your Transaction, it should delete your temp files automatically, as long as they were created within the Transaction scope.
Here you need to dispose the object of MailMessage.
For Ex.
// Sends email using SMTP with default network credentials
public static void SendEmailToCustomer(string To, string From, string BCC, string Subject, string Body, bool IsBodyHtml, string attachedPath = "") {
//create mail message
MailMessage message = !string.IsNullOrEmpty(From) ? new MailMessage(From, To) : new MailMessage(From, To);
//create mail client and send email
SmtpClient emailClient = new SmtpClient();
//here write your smtp details below before sending the mail.
emailClient.Send(message);
//Here you can dispose it after sending the mail
message.Dispose();
//Delete specific file after sending mail to customer
if (!string.IsNullOrEmpty(attachedPath))
DeleteAttachedFile(attachedPath);
}
//Method to delete attached file from specific path.
private static void DeleteAttachedFile(string attachedPath) {
File.SetAttributes(attachedPath, FileAttributes.Normal);
File.Delete(attachedPath);
}
Folks,
Using the System.Diagnostics.Process.Start("mailto: method of creating an email, is there a way to add a dynamic attachment (not a saved file) to the email?
I'm pretty much doing the same as this the person in this question but no-one has answered using the mailto: method.
Im just wondering if its possible, and how to do it.
I've tried this but to no avail:
System.IO.MemoryStream ms = new System.IO.MemoryStream(generatedReport.DocumentBytes);
System.Net.Mime.ContentType ct = new System.Net.Mime.ContentType(System.Net.Mime.MediaTypeNames.Application.Pdf);
Attachment attachment = new Attachment(ms, ct);
attachment.ContentDisposition.FileName = "output.pdf";
System.Diagnostics.Process.Start("mailto:myemail &SUBJECT=Test Subject BODY=Body Text&Attachment=" + attachment);
ms.Close();
Any and all help is appreciated
In general, the mailto: URL scheme does not support attachments. Thus, you should not use it at all if you need it to work reliably with attachments.
Apparently, some mail clients still support passing Attachment=..., but they expect the ... part to be the path of a local file. Thus, in your case, you need to
save the file to disk (you can use a temporary file name in a temporary folder) and then
pass the path of the file to your mailto: link.
Note that you will have to keep the file around until the user has actually sent the mail, so you might have to think about "cleaning up" those temporary files at a later time.