MailKit.Net.Imap read Gmail attachments when "Content-Disposition; inline" is set - c#

I have a c# console application that I use to search a Gmail account for emails with attachments and download them. I am using MailKit.Net.Imap.ImapClient to do this.
If the email has been sent with the "Content-Disposition; attachment" set then all works well. If the email has been sent with "Content-Disposition; inline" set, the ImapClient does not see the attachments and I can't download them.
Below is the code I use to do this. Does anyone have any idea how to fix this?
static public void mail_ReadEmail()
{
string mail_login = "your login here";
string mail_password = "your password here";
string mail_folderName = "your gmail folder name here";
// Get client & open folder
ImapClient client = mail_GetImapClient(mail_login, mail_password);
IMailFolder folder = mail_GetIMailFolder(client, mail_folderName);
// Get emails
DateTime startTime = DateTime.Now.AddMonths(-6);
IList<UniqueId> email = folder.Search(SearchQuery
.DeliveredAfter(startTime)
.And(SearchQuery
.FromContains("canon.co.nz")));
// Loop through emails (oldest first)
for (int i = email.Count - 1; i >= 0; i--)
{
// Get message and display subject and date
MimeMessage message = folder.GetMessage(email[i]);
Console.WriteLine(message.Subject + " - " + message.Date.DateTime.ToShortDateString());
// Show all attachments for this message
foreach (MimePart part in message.Attachments)
Console.WriteLine("\t* " + part.FileName);
}
}

You can use the BodyParts property instead of the Attachments property.
For example, you could do this:
foreach (MimePart part in message.BodyParts.OfType<MimePart> ().Where (x => x.IsAttachment || (/* other criteria that suggests an attachment */))
Console.WriteLine("\t* " + part.FileName);
If you want to treat all MimeParts with a Content-Disposition filename attribute or a Content-Type name attribute set, then you could do:
!string.IsNullOrEmpty (x.FileName)

Related

How to get mail sent successfully with MailKit IMap?

I'd like to know if my outbox mail has been sent successfully..
var client = new ImapClient();
....
var folders = client.GetFolders(client.PersonalNamespaces[0]);
var folder = client.GetFolder("已发送");//get sent mail floder in Chinese
var folderAccess = folder.Open(FolderAccess.ReadOnly);
string path = #"C:\temp\";
for (int i = folder.Count - 1; i >= 0; i--)
{
var message = folder.GetMessage(i);
}
You can't send messages via IMAP, you can only send them via SMTP.
Sending messages via SMTP do not put them into any IMAP folder. You have to put them there yourself.

Missing email from "name" when using AWS SES API in C#

When I send an email using AWS SES in a C# application the email names don't show in the received email - only the email addresses show.
The from/to emails I've added are strings in the form " Their Name". It's clearly understanding that as it's sending it to the right place, but just stripping out the names.
internal void SendEmail()
{
try
{
// Construct an object to contain the recipient address.
Destination destination = new Destination();
destination.ToAddresses = toList;
if (ccList.Count > 0) destination.CcAddresses = ccList;
if (bccList.Count > 0) destination.BccAddresses = bccList;
// Create the subject and body of the message.
Body bodyobj = new Body();
if(body!=null) bodyobj.Text = new Content(body);
if(html!=null) bodyobj.Html = new Content(html);
// Create a message with the specified subject and body.
Message message = new Message(new Content(subject), bodyobj);
// Assemble the email.
SendEmailRequest request = new SendEmailRequest();
request.Destination = destination;
request.Message = message;
request.Source = from;
AmazonSimpleEmailServiceClient client = new AmazonSimpleEmailServiceClient(Amazon.RegionEndpoint.EUWest1);
SendEmailResponse ser = client.SendEmail(request);
sent=true;
}
catch (Exception e)
{
errmsg = e.Message;
}
}
You can provide recipients with names in the standard email format
Fred Bloggs <fred.bloggs#exmaple.com>
If you specify your ToAddresses as a list of strings of that format, the name will be set properly.
This conforms to the Internet Message Format (rfc5322) spec. See section 3.4.

Retrieving Some Email Information

I'm trying to obtain some information from emails sent to an Outlook email. I've successfully connected to the Exchange Server and have been able to retrieve some information from emails with attachments (I am skipping emails without attachments).
What I Have: I can retrieve the attachment file name, the email date, and the email subject.
What I Need: I need to retrieve the sender name and email also. From what I've done, I can retreive the body of the email (in HTML), but not the body text only (requires Exchange 2013 - Hello MS advertising).
I'm new to C# and today is my first time to connect to the Exchange Server. I noticed from reading around that "find" is limited in what it can obtain, and that I'll need to bind the message in order to get more information from the email.
Code thus far:
foreach (Item item in findResults.Items)
if (item.HasAttachments) // && item.Attachments[0] is FileAttachment)
{
item.Load();
FileAttachment fileAttachment = item.Attachments[0] as FileAttachment;
date = Convert.ToString(item.DateTimeCreated);
name = Convert.ToString(fileAttachment.Name);
fileAttachment.Load("C:\\test\\" + fileAttachment.Name);
Console.WriteLine(name);
Console.WriteLine(item.Subject);
Console.WriteLine(date);
}
My question from here is if I do EmailMessage msg = EmailMessage.Bind ... what information will I need in order to grab more information?
Solved - for getting sender email and name as well as loading an attachment.
I used the EmailMessage class (just added it in the above loop, and added the variables to the beginning):
EmailMessage msg = (EmailMessage)item;
senderemail = Convert.ToString(msg.Sender.Address);
sendername = Convert.ToString(msg.Sender.Name);
I can then reproduce these on the console:
Console.WriteLine(senderemail);
Console.WriteLine(sendername);
Also, for loading an email's attaachment, I declared a byte[] variable at the beginning, loaded the attachment, converted it, and wrote its content to the console:
fileAttachment.Load();
filecontent = fileAttachment.Content;
System.Text.Encoding enc = System.Text.Encoding.ASCII;
string strFileContent = enc.GetString(filecontent);
Console.WriteLine(strFileContent);

compose email in outlook with attachment

In my application, I have a requirement where if a user clicks on invoice number the generated invoice statesment is attached to a composed email in outlook. Using code below i am able to send automated emails but i need to just compose and open the outlook window for user to review and edit the contents. Do not send. Kindly help.
public void pdfStatement(string InvoiceNumber)
{
InvoiceNumber = InvoiceNumber.Trim();
string mailServer = "server";
string fileName = InvoiceNumber;
string filePath = Server.MapPath("~/Content/reports/");
string messageBody = "Its an automated test email, please ignore if you receive this.";
CreateMessageWithAttachment(mailServer, filePath, fileName, messageBody);
}
public void CreateMessageWithAttachment(string mailServer, string filePath, string fileName, string messageBody)
{
MailMessage message = new MailMessage (
"user#domain.com",
"user#domain.com",
"TestEmail",
messageBody);
filePath = filePath + fileName + ".pdf";
// Create the file attachment for this e-mail message.
Attachment attach = new Attachment(filePath);
attach.Name = fileName + ".pdf";
// Add the file attachment to this e-mail message.
message.Attachments.Add(attach);
//Send the message.
SmtpClient client = new SmtpClient(mailServer);
var AuthenticationDetails = new NetworkCredential("user", "password");
client.Credentials = AuthenticationDetails;
client.Send(message);
}
not sure if this will help but how about u just create a form in tha page and allow user to type/see what they be sending.
Sample here
Also Preview button can help
EDIT:
Then u need to use Microsoft.Office.Interop.Outlook namespace to create a mail item.
First sample here
From the sample, the MailItem class(oMsg) also has a Display() Method which should display the created email.
Second sample (ASP.NET version)

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

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.

Categories

Resources