How to convert stream of MAPI properties to MapiCalendar and MapiContact

I am using .NET and Aspose.Email. I am trying to convert a stream of MAPI properties into MapiCalendar and MapiContact objects, by creating new, empty MapiCalendar or MapiContact and adding properties to it one by one. This works fine for most things, but some properties aren’t assimilated properly: For contacts, Email1, Email2, Email3 is lost. For calendar, event dates and recurrence is lost and no event shows up in outlook.

When I manually process and add the missing fields to the object it works, but I don’t want to go and look for all possible missing info and add it in manually.

There is no example for this type of operation in the documentation. Can you please provide some guidance?

(Important note: Some of the MAPI properties are named properties. The Aspose API provides many different ways of adding/setting properties to a MessageItem or MessageItemBase or Calendar or Contact. I’ve tried a bunch of different things, but nothing seems to work right.)

Hello @Stephanus ,

Thank you for contacting our support.

You can use the following sample code to load a MAPI item into a MapiMessage from a file or stream, and then, convert the resulting object into a MapiContact or MapiCalendar:

var msgItem = MapiMessage.Load("item.msg");
            
if (msgItem.SupportedType == MapiItemType.Contact)
{
    var mapiContact = (MapiContact)msgItem.ToMapiMessageItem();
}

if (msgItem.SupportedType == MapiItemType.Calendar)
{
    var mapiCalendar = (MapiCalendar)msgItem.ToMapiMessageItem();
}

Please spare a minute to share your feedback.

Thank you for the quick response!

With this code, the problem is exactly the same. I suspect it has something to do with the way I am adding properties to the objects. For some background: We are reading a raw FTS stream from an Exchange server, which means we only have a stream of raw MAPI properties - not a msg file. We have to build up the mapi object from scratch using only MAPI properties.

There are tagged properties and named properties. The named properties can be identified by a PSET_ID in combination with either a string OR a long int.

I’ve found that I get a NullReferenceException whenever I try to add a Named property that is identified by a string. That is, a property created with this method:
var mapiProperty = new MapiNamedProperty(PropertyTag, identifier.Name, info.PropertySet, Value.MapiData);

where identifier.Name is a string, this doesn’t seem to construct the property fully/correctly. (When I use message.SetProperty(mapiProperty) it does not raise an exception, but when I use message.Properties.Add(mapiProperty) it does).

The “Add” method on message.NamedProperties doesn’t seem to provide for a PidName property, only for PidLid and PidTag:
image.png (41.3 KB)

Hello @Stephanus ,

For better understanding, could you please share your current code example? Are you creating MapiProperties objects from raw FTS stream?

Thanks.

Yes, parsing the FTS stream, buildig MAPI properties from scratch, adding them to the MapiMessage.Properties collection, converting to MapiContact or MapiCalendar, then adding to folder inside PST file.

This is the ToMapiProperty() method on our parsed Property object that tries to build the new Aspose.MapiProperty from the contents it parsed from the FTS stream:

public MapiProperty AsMapiProperty()
{
    return Info switch
    {
        TaggedPropertyInfo
            => new MapiProperty(PropertyTag, Value.MapiData),
        NamedPropertyInfo { Identifier: NamedPropertyDisplayId identifier } info
            => new MapiNamedProperty(PropertyTag, identifier.DisplayId, info.PropertySet, Value.MapiData),
        NamedPropertyInfo { Identifier: NamedPropertyName identifier } info
            => new MapiNamedProperty(PropertyTag, identifier.Name, info.PropertySet, Value.MapiData),
        _ => null
    };
}

And then the calling code will look like this:

var properties = ftsStream.Parse();

var mapiMessage = new MapiMessage();
foreach (var property in properties)
{
    var mapiProperty = property.AsMapiProperty();
    mapiMessage.Properties.Add(mapiProperty);
}

var contact = (MapiContact)mapiMessage.ToMapiMessageItem();
pstContactsFolder.AddMessage(contact);
  • The normal MapiProperty and the MapiNamedProperty with the DisplayId works fine. But the MapiNamedProperty identified by a string (identifier.Name) can’t be added to the properties.

@Stephanus ,

Thanks for the code sample. We’ll investigate it and contact you asap.