I have created a Web Email Application, How do I view and save attached files?
I am using OpenPop, a third Party dll, I can send emails with attachments and read emails with no attachments.
This works fine:
Pop3Client pop3Client = (Pop3Client)Session["Pop3Client"]; // Creating newPopClient
int messageNumber = int.Parse(Request.QueryString["MessageNumber"]);
Message message = pop3Client.GetMessage(messageNumber);
MessagePart messagePart = message.MessagePart.MessageParts[1];
lblFrom.Text = message.Headers.From.Address; // Writeing message.
lblSubject.Text = message.Headers.Subject;
lblBody.Text=messagePart.BodyEncoding.GetString(messagePart.Body);
This second portion of code displays the contents of the attachment, but that's only useful if its a text file. I need to be able to save the attachment. Also the bottom section of code I have here over writes the body of my message, so if I receive an attachment I can't view my message body.
if (messagePart.IsAttachment == true) {
foreach (MessagePart attachment in message.FindAllAttachments()) {
if (attachment.FileName.Equals("blabla.pdf")) { // Save the raw bytes to a file
File.WriteAllBytes(attachment.FileName, attachment.Body); //overwrites MessagePart.Body with attachment
}
}
}
If anyone is still looking for answer this worked fine for me.
var client = new Pop3Client();
try
{
client.Connect("MailServerName", Port_Number, UseSSL); //UseSSL true or false
client.Authenticate("UserID", "password");
var messageCount = client.GetMessageCount();
var Messages = new List<Message>(messageCount);
for (int i = 0;i < messageCount; i++)
{
Message getMessage = client.GetMessage(i + 1);
Messages.Add(getMessage);
}
foreach (Message msg in Messages)
{
foreach (var attachment in msg.FindAllAttachments())
{
string filePath = Path.Combine(#"C:\Attachment", attachment.FileName);
if(attachment.FileName.Equals("blabla.pdf"))
{
FileStream Stream = new FileStream(filePath, FileMode.Create);
BinaryWriter BinaryStream = new BinaryWriter(Stream);
BinaryStream.Write(attachment.Body);
BinaryStream.Close();
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("", ex.Message);
}
finally
{
if (client.Connected)
client.Dispose();
}
for future readers there is easier way with newer releases of Pop3
using( OpenPop.Pop3.Pop3Client client = new Pop3Client())
{
client.Connect("in.mail.Your.Mailserver.com", 110, false);
client.Authenticate("usernamePop3", "passwordPop3", AuthenticationMethod.UsernameAndPassword);
if (client.Connected)
{
int messageCount = client.GetMessageCount();
List<Message> allMessages = new List<Message>(messageCount);
for (int i = messageCount; i > 0; i--)
{
allMessages.Add(client.GetMessage(i));
}
foreach (Message msg in allMessages)
{
var att = msg.FindAllAttachments();
foreach (var ado in att)
{
ado.Save(new System.IO.FileInfo(System.IO.Path.Combine("c:\\xlsx", ado.FileName)));
}
}
}
}
The OpenPop.Mime.Message class has ToMailMessage() method that converts OpenPop's Message to System.Net.Mail.MailMessage, which has an Attachments property. Try extracting attachments from there.
I wrote this quite a long time ago, but have a look at this block of code that I used for saving XML attachments within email messages sat on a POP server:
OpenPOP.POP3.POPClient client = new POPClient("pop.yourserver.co.uk", 110, "your#email.co.uk", "password_goes_here", AuthenticationMethod.USERPASS);
if (client.Connected) {
int msgCount = client.GetMessageCount();
/* Cycle through messages */
for (int x = 0; x < msgCount; x++)
{
OpenPOP.MIMEParser.Message msg = client.GetMessage(x, false);
if (msg != null) {
for (int y = 0; y < msg.AttachmentCount; y++)
{
Attachment attachment = (Attachment)msg.Attachments[y];
if (string.Compare(attachment.ContentType, "text/xml") == 0)
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
string xml = attachment.DecodeAsText();
doc.LoadXml(xml);
doc.Save(#"C:\POP3Temp\test.xml");
}
}
}
}
}
List<Message> lstMessages = FetchAllMessages("pop.mail-server.com", 995, true,"Your Email ID", "Your Password");
The above line of code gets the list of all the messages from your email using corresponding pop mail-server.
For example, to get the attachment of latest (or first) email in the list, you can write following piece of code.
List<MessagePart> lstAttachments = lstMessages[0].FindAllAttachments(); //Gets all the attachments associated with latest (or first) email from the list.
for (int attachment = 0; attachment < lstAttachments.Count; attachment++)
{
FileInfo file = new FileInfo("Some File Name");
lstAttachments[attachment].Save(file);
}
private KeyValuePair<byte[], FileInfo> parse(MessagePart part)
{
var _steam = new MemoryStream();
part.Save(_steam);
//...
var _info = new FileInfo(part.FileName);
return new KeyValuePair<byte[], FileInfo>(_steam.ToArray(), _info);
}
//... How to use
var _attachments = message
.FindAllAttachments()
.Select(a => parse(a))
;
Just in case someone wants the code for VB.NET:
For Each emailAttachment In client.GetMessage(count).FindAllAttachments
AttachmentName = emailAttachment.FileName
'----// Write the file to the folder in the following format: <UniqueID> followed by two underscores followed by the <AttachmentName>
Dim strmFile As New FileStream(Path.Combine("C:\Test\Attachments", EmailUniqueID & "__" & AttachmentName), FileMode.Create)
Dim BinaryStream = New BinaryWriter(strmFile)
BinaryStream.Write(emailAttachment.Body)
BinaryStream.Close()
Next
Related
I'm trying to make an program that send a file to a mobile device encrypted, and the device will get it in another program and decrypt it.
So far I've done the bluetooth connection:
private void Connect()
{
using (SelectBluetoothDeviceDialog bldialog = new SelectBluetoothDeviceDialog())
{
bldialog.ShowAuthenticated = true;
bldialog.ShowRemembered = true;
bldialog.ShowUnknown = true;
if (bldialog.ShowDialog() == System.Windows.Forms.DialogResult.OK )
{
if (bldialog.SelectedDevice == null)
{
System.Windows.Forms.MessageBox.Show("No device selected", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
BluetoothDeviceInfo selecteddevice = bldialog.SelectedDevice;
BluetoothEndPoint remoteEndPoint = new BluetoothEndPoint(selecteddevice.DeviceAddress, BluetoothService.ObexFileTransfer);
client = new BluetoothClient();
client.Connect(remoteEndPoint);
session = new ObexClientSession(client.GetStream(), UInt16.MaxValue);
session.Connect(ObexConstant.Target.FolderBrowsing);
tbConnectionDet.Text = string.Format("Connected to: {0}", selecteddevice.DeviceName);
}
}
}
Also I'm sending the file this way:
private void UploadFiles(string[] files)
{
long size = 0;
List<string> filestoupload = new List<string>();
foreach (string filename in files)
{
if (File.Exists(filename))
{
FileInfo info = new FileInfo(filename);
filestoupload.Add(filename);
size += info.Length;
}
}
using (FileForm upform = new FileForm(new List<string>(filestoupload),
false, session, size, null))
{
upform.ExceptionMethod = ExceptionHandler;
upform.ShowDialog();
lsvExplorer.BeginUpdate();
for (int i = 0; i <= upform.FilesUploaded; i++)
{
ListViewItem temp = new ListViewItem(new string[]{ Path.GetFileName(filestoupload[i]),
FormatSize(new FileInfo(filestoupload[i]).Length, false)},
GetIconIndex(Path.GetExtension(filestoupload[i]), false));
temp.Tag = false;
lsvExplorer.Items.Add(temp);
}
lsvExplorer.EndUpdate();
}
}
I'm using 32feet and BrechamObex libraries .
I have the following questions :
I want to send a public key from my phone to my computer then encrypt a file and send it back to my phone. After I receive the file, I want to decrypt it so I will need another program in order to do this. How can I send information from one program to another using bluetooth?
Whenever I send a file, the phone gets it, but the size it always 0
I am using ASP.Net MVC.
using (ExchangeServiceBinding exchangeServer = new ExchangeServiceBinding())
{
ICredentials creds = new NetworkCredential("username", "password");
exchangeServer.Credentials = creds;
exchangeServer.Url = "https://myexchangeserver.com/EWS/Exchange.asmx";
FindItemType findItemRequest = new FindItemType();
findItemRequest.Traversal = ItemQueryTraversalType.Shallow;
// define which item properties are returned in the response
ItemResponseShapeType itemProperties = new ItemResponseShapeType();
itemProperties.BaseShape = DefaultShapeNamesType.AllProperties;
findItemRequest.ItemShape = itemProperties;
// identify which folder to search
DistinguishedFolderIdType[] folderIDArray = new DistinguishedFolderIdType[1];
folderIDArray[0] = new DistinguishedFolderIdType();
folderIDArray[0].Id = DistinguishedFolderIdNameType.inbox;
// add folders to request
findItemRequest.ParentFolderIds = folderIDArray;
// find the messages
FindItemResponseType findItemResponse = exchangeServer.FindItem(findItemRequest);
// read returned
FindItemResponseMessageType folder = (FindItemResponseMessageType)findItemResponse.ResponseMessages.Items[0];
ArrayOfRealItemsType folderContents = new ArrayOfRealItemsType();
folderContents = (ArrayOfRealItemsType)folder.RootFolder.Item;
ItemType[] items = folderContents.Items;
// if no messages were found, then return null -- we're done
if (items == null || items.Count() <= 0)
{ return null; }
// FindItem never gets "all" the properties, so now that we've found them all, we need to get them all.
BaseItemIdType[] itemIds = new BaseItemIdType[items.Count()];
for (int i = 0; i < items.Count(); i++)
{
itemIds[i] = items[i].ItemId;
}
GetItemType getItemType = new GetItemType();
getItemType.ItemIds = itemIds;
getItemType.ItemShape = new ItemResponseShapeType();
getItemType.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
getItemType.ItemShape.BodyType = BodyTypeResponseType.HTML;
getItemType.ItemShape.BodyTypeSpecified = true;
GetItemResponseType getItemResponse = exchangeServer.GetItem(getItemType);
ItemType[] messages = new ItemType[getItemResponse.ResponseMessages.Items.Count()];
List<MailRecipientModel> model = new List<MailRecipientModel>();
for (int j = 0; j < messages.Count(); j++)
{
messages[j] = ((ItemInfoResponseMessageType)getItemResponse.ResponseMessages.Items[j]).Items.Items[0];
MailRecipientModel model1 = new MailRecipientModel();
model1.Subject = messages[j].Subject;
model1.FromAddress = messages[j].Sender.Item.EmailAddress;
model1.DisplayName = messages[j].Sender.Item.Name;
model1.Date = messages[j].DateTimeReceived.Date.ToString();
model1.MailBody = messages[j].Body.Value;
model1.MsgId = messages[j].ItemId.Id;
if (messages[j].Attachments != null) {
//
}
model.Add(model1);
}
return model;
}
This my code I wanna download attachment file and if attachment file is image so its display in browser.
I am using Microsoft ActiveSync Exchange Server.
If you know how to do so please help me.
public List<FileAttachment> getAttachmentFromExchangeAccount( ExchangeAccounts exchangeAccount, String attachmentId, String itemId) {
ExchangeService service = obtainExchangeService(exchangeAccount);
List<FileAttachment> fileAttachmentsEWS = new ArrayList<>();
try {
EmailMessage message = EmailMessage.bind(service, new ItemId(attachmentId), new PropertySet(ItemSchema.Attachments));
message.load();
for (Attachment attachment : message.getAttachments()) {
attachment.load();
if (attachment.getId().equals(itemId)) {
FileAttachment fileAttachment = (FileAttachment) attachment;
fileAttachment.load();
fileAttachmentsEWS.add(fileAttachment);
}
}
} catch (ServiceLocalException e) {
LOG.debug("OUT NOK loadAttachmentFile ServiceLocalException");
LOG.debug(e.getMessage());
} catch (Exception e) {
LOG.debug("OUT NOK loadAttachmentFile Exception");
LOG.debug(e.getMessage());
}
return fileAttachmentsEWS;
}
You should be using the GetAttachment operation https://msdn.microsoft.com/en-us/library/office/aa494316(v=exchg.150).aspx . There is a Proxy code sample https://blogs.msdn.microsoft.com/vikas/2007/10/15/howto-ews-use-getattachment-to-download-attachments-off-mailappointment/
I'm using MailKit library to handle emails, which has been working well. However, I'm trying to split emails into their constituent files a) Main email (no attachments) b) Individual attachment files, to store on the filesystem.
I can save the attachments individually, but can't seem to remove them from the email body code. I.e. they're getting saved along with the main email, so duplicating data. :/
I've tried:
foreach (MimePart part in inMessage.BodyParts)
{
if (part.IsAttachment)
{
// Remove MimePart < This function isn't available on the collection.
}
}
Have also tried:
var builder = new BodyBuilder();
foreach (MimePart part in inMessage.BodyParts)
{
if (!part.IsAttachment)
{
// Add MimeParts to collection < This function isn't available on the collection.
}
}
outMessage.Body = builder.ToMessageBody();
If anyone can help with this, I'd much appreciate it.
Solution implemented FYI:
private string GetMimeMessageOnly(string outDirPath)
{
MimeMessage message = (Master as fsEmail).GetMimeMessage();
if (message.Attachments.Any())
{
var multipart = message.Body as Multipart;
if (multipart != null)
{
while (message.Attachments.Count() > 0)
{
multipart.Remove(message.Attachments.ElementAt(0));
}
}
message.Body = multipart;
}
string filePath = outDirPath + Guid.NewGuid().ToString() + ".eml";
Directory.CreateDirectory(Path.GetDirectoryName(outDirPath));
using (var cancel = new System.Threading.CancellationTokenSource())
{
using (var stream = File.Create(filePath))
{
message.WriteTo(stream, cancel.Token);
}
}
return filePath;
}
And to get the attachments only:
private List<string> GetAttachments(string outDirPath)
{
MimeMessage message = (Master as fsEmail).GetMimeMessage();
List<string> list = new List<string>();
foreach (MimePart attachment in message.Attachments)
{
using (var cancel = new System.Threading.CancellationTokenSource())
{
string filePath = outDirPath + Guid.NewGuid().ToString() + Path.GetExtension(attachment.FileName);
using (var stream = File.Create(filePath))
{
attachment.ContentObject.DecodeTo(stream, cancel.Token);
list.Add(filePath);
}
}
}
return list;
}
You could retrieve all MimeParts that are attachments https://github.com/jstedfast/MimeKit/blob/master/MimeKit/MimeMessage.cs#L734 and then iterate over the all Multiparts and call https://github.com/jstedfast/MimeKit/blob/master/MimeKit/Multipart.cs#L468 for the attachments to remove.
The sample below makes a few assumptions about the mail e.g. there is only one Multipart some email client (Outlook) are very creative how mails are crafted.
static void Main(string[] args)
{
var mimeMessage = MimeMessage.Load(#"x:\sample.eml");
var attachments = mimeMessage.Attachments.ToList();
if (attachments.Any())
{
// Only multipart mails can have attachments
var multipart = mimeMessage.Body as Multipart;
if (multipart != null)
{
foreach(var attachment in attachments)
{
multipart.Remove(attachment);
}
}
mimeMessage.Body = multipart;
}
mimeMessage.WriteTo(new FileStream(#"x:\stripped.eml", FileMode.CreateNew));
}
Starting with MimeKit 0.38.0.0, you'll be able to use a MimeIterator to traverse the MIME tree structure to collect a list of attachments that you'd like to remove (and remove them). To do this, your code would look something like this:
var attachments = new List<MimePart> ();
var multiparts = new List<Multipart> ();
var iter = new MimeIterator (message);
// collect our list of attachments and their parent multiparts
while (iter.MoveNext ()) {
var multipart = iter.Parent as Multipart;
var part = iter.Current as MimePart;
if (multipart != null && part != null && part.IsAttachment) {
// keep track of each attachment's parent multipart
multiparts.Add (multipart);
attachments.Add (part);
}
}
// now remove each attachment from its parent multipart...
for (int i = 0; i < attachments.Count; i++)
multiparts[i].Remove (attachments[i]);
I created an application, that downloads emails and attachments as well using Mailkit.
I faced one problem: E-Mails sent from iOS with attached pictures were not processed correctly. MailKit did not add the images to the Attachments list.
I used this method to get only the text of the message:
private static string GetPlainTextFromMessageBody(MimeMessage message)
{
//content type needs to match text/plain otherwise i would store html into DB
var mimeParts = message.BodyParts.Where(bp => bp.IsAttachment == false && bp.ContentType.Matches("text", "plain"));
foreach (var mimePart in mimeParts)
{
if (mimePart.GetType() == typeof(TextPart))
{
var textPart = (TextPart)mimePart;
return textPart.Text;
}
}
return String.Empty;
}
This is the method I used to download only the .jpg files:
foreach (var attachment in message.BodyParts.Where(bp => !string.IsNullOrEmpty(bp.FileName)))
{
if (attachment.FileName.ToLowerInvariant().EndsWith(".jpg"))
{
//do something with the image here
}
}
I want ask if the folder exist, if no create it.I try the foloowing but when I became to the bold row below in the code I get error:NO Command received in Invalid state.
using (ImapClient ic = new ImapClient(imapAddr, myEmailID, myPasswd, ImapClient.AuthMethods.Login, portNo, secureConn))
{
bool headersOnly = false;
ic.SelectMailbox("INBOX");
Lazy<MailMessage>[] messages = ic.SearchMessages(SearchCondition.Unseen(), headersOnly);
foreach (Lazy<MailMessage> message in messages)
{
MailMessage m = message.Value;
AE.Net.Mail.Imap.Mailbox IsExistFolder = ic.Examine("INBOX/zipi4");
if (IsExistFolder == null)
{
ic.CreateMailbox("INBOX/zipi4");
}
string s = "INBOX/zipi2";
**ic.MoveMessage(m.Uid, s);**
ic.Expunge();
TextWriter writer1 = File.CreateText("Y:\\perl4.txt");
m.Save(writer1);
}
}
I searched a lot how to read an email from gmail and then mark it as unread (unseen), now that I found I wanted to share with everyone.
using library http://mailsystem.codeplex.com/
Source: http://mailsystem.codeplex.com/discussions/269058
add reference: activeup.net.common, activeup.net.imap4, activeup.net.mail
code:
Imap4Client imap = new Imap4Client();
imap.ConnectSsl("imap.gmail.com", 993);
imap.Login("aaaaa#gmail.com", "xxxxxxx");
imap.Command("capability");
Mailbox inbox = imap.SelectMailbox("inbox");
int[] ids = inbox.Search("UNSEEN");
if (ids.Length > 0)
{
ActiveUp.Net.Mail.Message msg_first = inbox.Fetch.MessageObject(ids[0]);
//ignore this gmail_data stuff // undefined in this scope // checking to make sure it's a "new" unread msg
//if (gmail_data != msg_first.Date.ToString())
//{
// gmail_data = msg_first.Date.ToString();
XElement xmail = new XElement("gmail",
new XAttribute("count", ids.Length.ToString()),
new XAttribute("modified", msg_first.Date.ToString())
);
string name = "", address = "", from = "";
Regex reg_name = new Regex("\"[^\"]+");
Regex reg_address = new Regex("<[^>]+");
ActiveUp.Net.Mail.Message msg = null;
for (var i = 0; i < ids.Length; i++)
{
msg = inbox.Fetch.MessageObject(ids[i]);
from = msg.HeaderFields["from"];
name = reg_name.Match(from).Value.Replace("\"", "");
address = reg_address.Match(from).Value.Replace("<", "");
xmail.Add(new XElement("entry",
new XAttribute("id", msg.MessageId),
new XAttribute("modified", msg.Date.ToString()),
new XAttribute("name", name),
new XAttribute("address", address),
new XElement("subject", msg.Subject),
new XElement("body-text", msg.BodyText.TextStripped),
new XElement("body-html", msg.BodyHtml.Text)
));
//mark as unread
var flags = new FlagCollection();
flags.Add("Seen");
inbox.RemoveFlags(ids[i], flags);
}
File.WriteAllText("gmail.xml", xmail.ToString());
}
}
When you get all e-mail´s from server, the API automaticaly marks all e-mail´s as "seen/readed", and i think there´s no way to use the "search method" filtering by messageId, so you must get all e-mail to mark one (seen) e-mail as unread.
You should get allways just the "unread massages" and add on a list the messageId of the e-mail´s that you want to mark as "unread", then you must pass the list to the method bellow, that will mark as unread all messages of the list.
Possible code:
public void MarkAsUnread(List<string> messageIdList)
{
Mailbox inbox = Client.SelectMailbox("inbox");
int[] ids = inbox.Search("ALL");
int ListCount = messageIdList.Count;
int MarkedAsUnread = 0;
if (ids.Length > 0)
{
ActiveUp.Net.Mail.Message msg = null;
for (var i = 0; i < ids.Length; i++)
{
msg = inbox.Fetch.MessageObject(ids[i]);
// if messageId is on the list, mark as unread.
if (String.Join(",", messageIdList).Contains(msg.MessageId))
{
var flags = new FlagCollection { "Seen" };
inbox.RemoveFlagsSilent(i+1, flags);
MarkedAsUnread = MarkedAsUnread + 1;
}
// optimization
if (MarkedAsUnread == ListCount)
{
break;
}
}
}
}
*If you really don´t want to get all, maybe you could filter by date using some code like that:
var box = imap.SelectMailbox("inbox");
var ids = box.Search("OR (CC #cc.lieser-online.de) (HEADER Envelope-To #cc.lieser-online.de)");