Custom MAPI Property Read

I need to access a custom MAPI property on existing mail messages in Exchange. The NamedProperties collection data store only appears to be populated after a MailMessage is saved to disk, read back in and converted to MAPI format (I believe this is a known workaround). However, the custom property I need is not persisted when saving to an MSG file (either manually in Outlook, or via Aspose) so the workaround doesn’t work in this situation. Is ther eanother way to access MAPI properties for existing items?

Hi Clark,


Thank you for contacting support.

If you are fetching the message from Exchange Server then the fetched message will always be in MailMessage format, and to read the custom properties from the fetched message, you have to convert it to MapiMessage object. Below is a sample code for your reference,

C#

var message = MapiMessage.FromMailMessage(MailMessage.Load((“testing.msg”)));
foreach (MapiNamedProperty namedProperty in message.NamedProperties.Values)
{
if (namedProperty.Oom == “PropertyName”)
{
string propertyValue = namedProperty.GetString();
Console.WriteLine(“Named Property :” + propertyValue);
}
}


Please note, to exhibit the usage I have read the MailMessage from disk and then converted it to MapiMessage. Instead you can always load the MapiMessage directly from the disk using the MapiMessage.FromFile method. Moreover, I would request you to please use the latest version of Aspose.Email for .NET v1.9.0 for your testing.

Regards,

Thanks for your response. My MailMessage seems to be missing all of it’s named properties (except one) for some reason, ie. after using

mapiExchangeMsg = MapiMessage.FromMailMessage(exchangeMsg);

the NamedProperties.Values collection is empty except for one entry. If I write the same Exchange MailMessage to disk (MSG) with MailMessage.Save and open with OutLookSpy this also verifies named properties are missing. If I save the email as an MSG file using OutlookSpy or Outlook then I can open it with MAPIMessage.FromFile and everything is there.

The issue appears to be with MailMessage rather than Exchange. If I load the MSG file (verified to have all properties as above) into a MailMessage using MailMessage.Load, then save using

mailWorkMsg.Save(@"c:\temp\OutlookSpy Record Retention MailMessage.msg", MailMessageSaveType.OutlookMessageFormatUnicode);

then read this back into a MAPI message using MapiMessage.FromFile the properties are gone. I'll send you the example MSG file containing all the properties.

Attached is the sample MSG file with all properties…

Also, is it possible that the following earlier support issue could be relavent?:

This does not work if you create a new MapiMessage from scratch.

If you create a new MapiMessage (not load from file), then MapiMessage.NamedPropertyMapping is null.

MapiMessage mapi = new MapiMessage();
MapiPropertyCollection namedProperties = mapi.NamedProperties;
MapiNamedPropertyMappingStorage mappingStorage = mapi.NamedPropertyMapping;
MapiProperty property = new MapiProperty(WaveMapiPropertyTag.PR_WAVESOFT_FROM, Encoding.Unicode.GetBytes("test value - hello 123"));
mappingStorage.AddNamedPropertyMapping(property, WaveMapiPropertyTag.GetPropertyName(WaveMapiPropertyTag.PR_WAVESOFT_FROM), new Guid()); // <-- will crash because 'mappingStorage' is null
mapi.SetProperty(property);
Ie. it seems that the NamedProperty collection is only populated for a MapiMessage loaded from disk, not created new or perhaps created from a MailMessage. this wouldn't account for why MailMessage.Save doesn't write the named properties to the MSG file but seemed somewhat similar so thought I would mention it. Thanks...

Hi Clark,


First of all, please accept my sincere apology for the delayed response.

I have worked on your given scenario and I am getting similar results as of yours with a sample of my own when I first loaded the message into an instance of MailMessage and then loaded the MailMessage into an instance of MapiMessage. On the contrary, if I load the same message directly into an instance of MapiMessage (without first saving the message on disk with MailMessage) then all custom properties can be properly read. In reference to these results, I would request you to please try this procedure at your end and feed us back with your results.

In reference to your request regarding the custom properties for a newly created message, please try the below given sample source. Upon executing the sample code, you will notice that Named Property can be saved and retrieved from a new MapiMessage with out any problem.

Please note, I have provided a general scenario to add a string type property. You may amend the code according to your needs.

C#

var message = new MapiMessage("from@domain.com", "to@domain.com", “subject”, “body”);
var storage = message.NamedPropertyMapping;
var stringProperty = new MapiProperty(0x00000000F001001f, Encoding.Unicode.GetBytes(“this is a test property unicode string value”));
message.SetProperty(stringProperty);
storage.AddNamedPropertyMapping(stringProperty, “testProperty”, new Guid());
message.Save(“property.msg”);

var loadedMessage = MapiMessage.FromFile(“property.msg”);
var propertyValue = message.GetPropertyString(0x00000000F001001f);
Console.WriteLine(propertyValue);

Please feel free to write back in case of further inquiries.
Regards,

Thanks for your efforts to resolve my issue. The results I noted earlier were just diagnostic to determine the root cause of the issue. The basic scenario is that I am reading Exchange and need to check a particular custom MAPI property value for each message. For this reason I am starting with a MailMessage collection with property values already set. I know the property is set in the Exchange message but can’t get to it via MailMessage named property collection to check it. If I save to disk and read it back in as a MAPI message it isn’t there either. My intuition is that MailMessage doesn’t preload all custom MAPI properties to the named attribute by default, but perhaps there is a way to request the specific value I need (PTDOCREF). Hope this helps to clarify and thanks for the assistance.

Hi Clark,


Thank you for your continues efforts to sort out this problem.

Could you please clarify further, how are you fetching the messages from exchange and most importantly how have you set the custom MAPI properties for the messages on exchange? If possible, please share the sample code for our review.

Please note that Aspose.Email recommends you to use MapiMessage class for Outlook type messages (.msg). MapiMessage reserves all MAPI properties if message can directly be fetched into it. In case the scenario restricts the direct fetching of message into an instance of MapiMessage and you have to alternatively first load the message in MailMessage and then into MapiMessage, there is a chance that some MAPI properties can be removed from the original message.

Regards,

The property in question was set by an email archiving system and contains a key value for lookup in the archive (the message itself, in Exchange, is unchanged other than having the property set). You will see this property value in the test email I provided.

In this situation, I must drive off of Exchange - I'm reading it with Exchange Web Service Client, EWS.ListMessages for each folder then EWS.FetchMessage with unique id to get each specific message in detail (MailMessage format). I am under the impression that one must use MailMessage for direct Exchange access.

There is a FetchMessage overload that also provides an Extended Properties array - might this be used? Wasn't sure if this was for Exchange custom properties versus MAPI extended properties...

Hi,


Thank you for elaborating the scenario.

I have logged an investigative ticket and sought help from the development team in this regard. The ticket Id for your reference is NETWORKNET-33344. As soon as we receive further updates from the development end, we will be more than happy to share that here.

Please accept our apologies for your inconvenience.

Hi Clark,


Thank you for your patience.

We are currently investigating the issue discussed in this thread. To probe further into this matter, we will require the original EML file that you can save by calling the ExchangeWebServiceClient.FetchMessage, and save the received MailMessage without converting it to MapiMessage. Along with that, we also require the name/Id of the NamedProperty that you are looking for. Could you please confirm if it is “PTDOCREF” as discussed in one of your previous replies.

Regards,