MailKit From Address - c#

Im using mailKit in asp mvc core to collect email from a IMAP mailbox.
I return the message using the command
var message = inbox.GetMessage(uid)
This returns all the results of the message. From here i want to access the sender email address (not including the name). After breakpointing on the above line i can see that the variable message has the following property
message
-From
--From(Array)
---From(item)
----Name (name of the sender)
----Address(email of the sender)
When referencing the above above using the message i am able to receive the name, however the address is not listed (within intelisence, nor will it build)
var name = message.From[0].Name.ToString()
Does anyone know why this would be visible as properties of the variable but not accessible via the code?
i simply want to
var name = message.From[0].Name.ToString()

The MimeMessage.From property is a InternetAddressList (more-or-less List<InternetAddress>).
InternetAddress is an abstract base class for MailboxAddress and GroupAddress which only contains a Name property as you've discovered.
In order to get the Address, you first need to cast it to a MailboxAddress... but only if it is actually a MailboxAddress or you'll get a cast exception.
InternetAddressList has a convenience property called Mailboxes which can be used to iterate over a flattened list of the MailboxAddresses contained within.

You can use this code block.
message.From.OfType<MailboxAddress>().Single().Address;

Another solution:
message.From.Mailboxes.Single().Address;

Related

How to reply to an email using the EWS Managed API?

I have created an application that uses the EWS Managed API 2.2.
This application uses pull notifications to get new emails and saves a copy of the email in a database.
Then in the application I want to get the email from database and reply to it.
In order to reply to the message, I need to retrieve it from EWS using the ItemId I have stored in my database.
Of course I can create a new EmailMessage and send it but then the new email will have a different ConversationId which is not acceptable for the application scenario.
So, in order to achieve this I use the the following line of code
EmailMessage.Bind(service, itemId);
For this method to work I have to instantiate the ItemId from my database but the ItemId constructor takes as parameter only the UniqueId, and creates it with null ChangeKey.
If I use this ItemId (with null ChangeKey) I get the following error:
Microsoft.Exchange.WebServices.Data.ServiceResponseException: The specified object was not found in the store.
I think that this is because of the null ChangeKey. Am I correct?
Is there a workaround about this?
Instead of identifying a message by ItemId, use EntryID. Using EntryID, you can bind to the same email without needing ChangeKey.
Here is the definition of such property:
ExtendedPropertyDefinition EntryIDProperty = new ExtendedPropertyDefinition(0x0FFF, MapiPropertyType.Binary);
When you do your search for messages, make sure you instruct EWS to include such property in the list of retrieved items.
Here is an example to obtain EntryIDs when you invoke FindItems:
ExtendedPropertyDefinition EntryIDProperty = new ExtendedPropertyDefinition(0x0FFF, MapiPropertyType.Binary);
ItemView item_view = new ItemView(10) { PropertySet = new PropertySet(ItemSchema.Id, EntryIDProperty) };
var result = service.FindItems(WellKnownFolderName.Inbox, item_view);
foreach (var item in result.Items)
{
byte[] entry_id = (byte[])item.ExtendedProperties.Single(x => x.PropertyDefinition == EntryIDProperty).Value;
string entry_id_hex = ByteArrayToHexString(entry_id); //This is the entry ID that you should store
}
Use the following method to convert a EntryID to ItemID if you want to use EmailMessage.Bind:
This method accepts string EntryID.
mailbox_address is the SMTP address of the mailbox (e.g. test#domain.com)
'service' is the ExchangeService object.
private ItemId ConvertEntryIdToItemId(string entryid, string mailbox_address, ExchangeService service)
{
AlternateId id = new AlternateId(IdFormat.HexEntryId, entryid, mailbox_address);
AlternateId new_id = (AlternateId)service.ConvertId(id, IdFormat.EwsId);
ItemId item_id = new_id.UniqueId;
return item_id;
}
Now you can use the returned ItemId to bind your EmailMessages.
The specified object was not found in the store.
That error generally means that you don't have rights to the Mailbox your trying to access or the Item your trying to access no longer exists in the store. Eg in a pull notification application that can mean the Item that you being notified about has already been deleted or moved to another folder (in each of these case the Item will be assigned a new Id). If you also listing to Move event you should be able to see the corresponding move event which will have the OldItemId that correlates the newMailEvent notification.
The Change Key only matters when your updating an Item so in the case the error you getting on Bind means that Item your trying doesn't exist (or has been moved) or you don't have rights to access it binding with just the UniqueId is perfectly okay see also https://msdn.microsoft.com/en-us/library/office/dn605828(v=exchg.150).aspx
Cheers
Glen

EWS API get Sender name when Cc information is missing

In work we have service mailbox and suddenly started coming mails with attachement daily, no one know why and how to stop that and nobody need that.
So im writing deleting script and i dont know how to detect/find these emails, because Cc field is blank and email with same Subject from same email address is already coming but difference is between alias, how can i read information from the image ?
I need declare a SearchFilter like
SearchFilter subjectFilter =
new SearchFilter.ContainsSubstring(ItemSchema.?WHATHERE?, "JOBRUN <something#company.com>");
Thank you :-)
If I do understand you correctly, and based on your screenshot, you want to get those emails that have the string JOBRUN in their Display Name (not in their Subject as your variable name states).
Altough I'm not sure if the following does the filtering based on the email-address of the sender only or additionally based on the sender's displayname (the documentation is pretty poor...), you could try the following:
var filter = new SearchFilter.ContainsSubstring(EmailMessageSchema.Sender, "JOBRUN");

Exchange EWS Managed API Error while Updating EmailMessage on certain properties

I am working against the Exchange 2010 EWS Managed API and trying to update emails (EmailMessage).
While updating the EmailMessage's Sender.Name property, I get an exception upon Update(), but if I try to update the EmailMessage's Subject, it works just fine.
private void UpdateEmail(ItemId itemId)
{
try
{
EmailMessage emailMessage = EmailMessage.Bind(service, itemId, new PropertySet(EmailMessageSchema.Sender, EmailMessageSchema.Subject));
// Test 1 - this works:
emailMessage.Subject = "Testing";
emailMessage.Update(ConflictResolutionMode.AlwaysOverwrite);
// Test 2 - this does NOT work (if I comment out the previous 2 lines btw):
emailMessage.Sender.Name = "John Smith";
emailMessage.Update(ConflictResolutionMode.AlwaysOverwrite); // exception thrown
...
I get the following error from Test 2:
The request failed schema validation: The element 'Updates' in namespace 'http:/
/schemas.microsoft.com/exchange/services/2006/types' has incomplete content. Lis
t of possible elements expected: 'AppendToItemField, SetItemField, DeleteItemFie
ld' in namespace 'http://schemas.microsoft.com/exchange/services/2006/types'.
EWS doesn't support changing the Sender address via the Strongly typed properties like you are trying. The only way they maybe successful is to modify the underlying extended properties and generating oneoff or wrapped entry-id where applicable the props you need to update are
PR_SENDER_ADDRTYPE_W
PR_SENDER_EMAIL_ADDRESS_W
PR_SENDER_NAME_W
PR_SENDER_ENTRYID
PR_SENDER_SEARCH_KEY
PR_SENT_REPRESENTING_EMAIL_ADDRESS_W
PR_SENT_REPRESENTING_ADDRTYPE_W
PR_SENT_REPRESENTING_NAME_W
PR_SENT_REPRESENTING_ENTRYID
PR_SENT_REPRESENTING_SEARCH_KEY
Note there maybe others as well you need to use a MAPI editor like OutlookSpy of MFCMapi to look at an item yourself.
Cheers
Glen

Exchange EWS Managed API - Undelivarable mail notification does not have the DateTimeReceived property

When finding items from a Exchange 2010 Server journaling inbox, there are some notifications on undelivered mails.
When processing these emails and trying to read the DateTimeReceived property, I get an ServiceObjectPropertyException with the error:
You must load or assign this property before you can read its value.
Is there a way of identifying such emails, or loading the DateTimeReceived property (even it will be null)?
My Code is something like this:
FindItemsResults<Item> mails = folder.FindItems(searchConditions, countConstraint);
foreach (Item item in mails)
{
EmailMessage email = (EmailMessage)item;
email.Load();
DateTime receivedTime = email.DateTimeReceived;
....
}
Those emails are from a journaling mailbox that has a copy of monitored mailbox every email sent to it.
The specific emails that do not have this property, are notifications about emails sent from one of those mailboxes, but could not be delivered.
Through MFCMapi I was able to view the message, and the PR_MESSAGE_DELIVERY_TIME property is set.
I don't think DateTimeReceived is considered a first class property so you need to load your email with specific properties.
email.Load(new PropertySet(ItemSchema.DateTimeReceived));
try ((MailItem)item).DateTimeReceived - for reference see
http://gsexdev.blogspot.com/2011/08/using-allitems-search-folder-from.html
http://social.technet.microsoft.com/Forums/en-US/exchangesvrdevelopment/thread/8c71ace4-43d2-4ba2-88f2-16376dad828f
http://msdn.microsoft.com/en-us/library/microsoft.exchange.data.transport.mailitem.datetimereceived%28v=EXCHG.80%29.aspx

How to insert an attachment to a System.Net.Mail.mailMessage by using Body properties

I need to send email with attachment. No problem if I do it by myself, but...
Inside the company I work for, I need to pass through a web service awaiting an email and a body.
I know that the implementation of this service use System.Web.mail.Mailmessage doing probably something like this:
MailMessage mm = new MailMessage();
mm.to = email_;
mm.body = body_;
...
So, is there a way to create a string that'll contain my attachement so I can send it to the web service ?
thx.
--Edition--
I must use a class "TheCompanyMail" that has 2 properties (to,body) and one method (send). This class is a proxy to a webservice. This webservice is the one that really sends the mail.
The problem is that I need to add an attachement to the mail and really don't know how to do it.
Example
File f = MyFuturAttachementFile;
TheComapyMail m = new TheCompanyMail();
m.to = "myCustomer#Company.com"
m.body = "Here is the file you're waiting for:"+f.ToString(); //this of course doesn't work !!!
m.send();
So I'm wondering if I can format the string of the body property to add attachement ?
I'm not sure if I'm right, but in my opinion there is no way to pass attachments by adding them in a string to message body. The main why-not argument is safety. I don't think that Microsoft could allow this class to behave like this...
You can't do it that way, you need to add it to the Attachements property of the MailMessage.
Why don't you store the file somewhere else where they can access it and just send them a link to it instead?
You could create an Html email where the "attachment" is actually link to download the file rather than an actual email attachement.

Categories