MapiMessageItemBase / IMapiMessageItem

Hello,
A quick simple question and I hope I can get a quick reply on this:

How to detect the type of MapiMessageItemBase / IMapiMessageItem
ie, to check if it’s a MapiContact or MapiCalendar or MapiMessage etc ?

This type I mean:

@australian.dev.nerds

A ticket has been logged as EMAILNET-40786 to detect the type of MapiMessageItemBase and IMapiMessageItem. We will inform you once there is an update available on it.

@australian.dev.nerds

Please use the following code example to achieve your requirement.

public IMapiMessageItem ToMapiMessageItem(MapiMessage msg)
{

    if (msg.MessageClass.StartsWith("IPM.Note", StringComparison.OrdinalIgnoreCase) ||
msg.MessageClass.StartsWith("REPORT.IPM.Note", StringComparison.OrdinalIgnoreCase))
    {
return msg;
    }

    if (msg.MessageClass.StartsWith("IPM.StickyNote", StringComparison.OrdinalIgnoreCase))
    {
return (MapiNote)msg.ToMapiMessageItem();
    }

    if (msg.MessageClass.StartsWith("IPM.Contact", StringComparison.OrdinalIgnoreCase))
    {
return (MapiContact)msg.ToMapiMessageItem();
    }

    if (msg.MessageClass.StartsWith("IPM.DistList", StringComparison.OrdinalIgnoreCase))
    {
return (MapiDistributionList)msg.ToMapiMessageItem();
    }

    if (msg.MessageClass.StartsWith("IPM.Activity", StringComparison.OrdinalIgnoreCase))
    {
return (MapiJournal)msg.ToMapiMessageItem();
    }

    if (msg.MessageClass.Equals("IPM.Appointment", StringComparison.OrdinalIgnoreCase)
|| msg.MessageClass.StartsWith("IPM.Appointment", StringComparison.OrdinalIgnoreCase)
|| msg.MessageClass.StartsWith("IPM.Schedule.meeting.", StringComparison.OrdinalIgnoreCase))
    {
return (MapiCalendar)msg.ToMapiMessageItem();
    }

    if (msg.MessageClass.StartsWith("IPM.Task", StringComparison.OrdinalIgnoreCase))
    {
return (MapiTask)msg.ToMapiMessageItem();
    }

    throw new NotSupportedException(
string.Format("The {0} message class is not supported by now", msg.MessageClass));
}

1 Like

Hello,
Very useful function, very helpful…

  1. Strange that this is not available as a property to MapiMessage/MapiMessageItem like MapiType to return an Enum like this:
    Public Enum MapiType As Byte
    Message = 0
    Contact = 1
    Calendar = 2
    DistList = 3
    Journal = 4
    Note = 5
    Task = 6
    Unknown = 7
    End Enum

  2. IPM.Document for DocumentItem, which can be ANY kind of file, according to MS, even executables, just please advise when extracting storages, how to save such files with their original name/extension?

  3. In case of IPM.Note/Message I save the message as eml/msg
    In case of IPM.Contact I will save as vcf and IPM.Appointment/Calendar goes to ics
    The question is what format your devs recommend to save IPM.StickyNote / IPM.DistList and IPM.Activity/Journal ?
    For example, notes shall be saved in html/rtf/mhtml or just like normal messages as eml?
    If you have a special save structure for Note/DistList/Journal please share the sample code?
    Best :slight_smile:

@australian.dev.nerds

PersonalStorage pst = PersonalStorage.FromFile(MyDir + "in.pst");

FolderInfo folder = pst.RootFolder.GetSubFolder("Files");

Aspose.Email.Storage.Pst.MessageInfoCollection coll = folder.GetContents();

foreach (Aspose.Email.Storage.Pst.MessageInfo info in coll)
{
    Console.WriteLine("info.MessageClass = " + info.MessageClass);

    if (info.MessageClass == "IPM.Document")
    {
        Console.WriteLine("Its Word doc");
        MapiMessage mapi = pst.ExtractMessage(info);

        if (mapi.Attachments.Count > 0)
            mapi.Attachments[0].Save(MyDir + mapi.Attachments[0].FileName);
    }
}

We have logged your other requirements in our issue tracking system as EMAILNET-40814.

1 Like

Hello,

Using this:
For Each MyMSG As MapiMessage In MyFolder.EnumerateMapiMessages
If MyMSG… = “MapiType.Document” Then
If MyMSG.Attachments.Count > 0 Then
For Each MyAttachment As Email.Mapi.MapiAttachment In MyMSG.Attachments
MyAttachment.Save(…)

  1. For “MapiType.Document”, needed to use For Each to save attachments, or I can be sure that “MapiType.Document” will only have 1 single attachment?

  2. Email.Mapi.MapiAttachment has 3 name properties, all returning the same value for “MapiType.Document” at least:
    .DisplayName / .FileName / .FileName
    Please advise the difference between these 3 and which one is safe to be guaranteed to have a value?

  3. Please advise what’s IPM.AbchPerson? And how to save it?

  4. And the worst thing to happen (I’m not sure if it will happen at all or under which conditions), anyway:
    IPM.OLE.Class: Exception item of a recurrence series
    How to deal with this? Ignore or it’s kinda exception message so I can save as plain text etc to review?
    Thanks

@australian.dev.nerds

You can iterate over attachment collection and save them.

MapiAttachment.DisplayName property returns the display name of the ole object and MapiAttachment.FileName property returns attachment’s base filename and extension.

A ticket EMAILNET-40817 has been logged for this requirement.

Please share Visual Studio application to reproduce this issue. We will investigate the issue and provide you information on it.

1 Like

Hi,
Sorry my typo, it was:
.DisplayName / .FileName / .LongFileName
So .DisplayName is rolled out since it might be wrong.
Between .FileName / .LongFileName which one should be used to save the attachment?
Because I’m getting the same string for both .FileName and .LongFileName so can’t distinguish between them (help is useless as usual)

  • And it will be guaranteed to have a value? I mean is is possible that .FileName / .LongFileName will be null or String.Empty?
    Best.

@australian.dev.nerds

A ticket has been logged as EMAILNET-40818 in our issue tracking system. We will inform you once there is an update available on it.

The file name should not be empty or null. If you have any MSG or EML file that contains such attachments, please share them here for testing.

@australian.dev.nerds

Regarding EMAILNET-40818, the MapiAttachment.FileName and MapiAttachment.LongFileName properties represent PidTagAttachFilename and PidTagAttachLongFilename MAPI properties respectively.

MapiAttachment.FileName: “The file name is restricted to eight characters plus a three-character extension.”
MapiAttachment.LongFileName: “it can be up to 256 characters long, including the filename, extension, and separator period.”

For Windows platform you should use the LongFileName property as suggested file name for saving an attachment.

@australian.dev.nerds,

  1. We have added the MapiItemType enum that represents a MAPI item type that can be explicitly converted into an object of the corresponding class derived from the IMapiMessageItem interface.
    This avoids the users from checking the MessageClass property in order to convert the item.
    Usage:
foreach (var messageInfo in folder.EnumerateMessages())
{
    var msg = pst.ExtractMessage(messageInfo);

    switch (msg.SupportedType)
    {
        // Non-supported type. MapiMessage cannot be converted to an appropriate item type.
        // Just save in MSG format.
        case MapiItemType.None:
            msg.Save($@"{fileName}.msg");
            break;
        // An email message. Save in EML format.
        case MapiItemType.Message:
            msg.Save($@"{fileName}.eml", SaveOptions.DefaultEml);
            break;
        // A contact item. Can be converted to MapiContact.
        // Save in VCF format.
        case MapiItemType.Contact:
            ((MapiContact)msg.ToMapiMessageItem()).Save($@"{fileName}.vcf", ContactSaveFormat.VCard);
            break;
        // A calendar item. Can be converted to MapiCalendar.
        // Save in ICS format.
        case MapiItemType.Calendar:
            ((MapiCalendar)msg.ToMapiMessageItem()).Save($@"{fileName}.ics", AppointmentSaveFormat.Ics);
            break;
        // A distribution list. Can be converted to MapiDistributionList.
        // Save in MSG format.
        case MapiItemType.DistList:
            var dl = (MapiDistributionList)msg.ToMapiMessageItem();
            dl.Save($@"{fileName}.msg");
            break;
        // A Journal entry. Can be converted to MapiJournal.
        // Save in MSG format.
        case MapiItemType.Journal:
            var journal = (MapiJournal)msg.ToMapiMessageItem();
            journal.Save($@"{fileName}.msg");
            break;
        // A StickyNote. Can be converted to MapiNote.
        // Save in MSG format.
        case MapiItemType.Note:
            var note = (MapiNote)msg.ToMapiMessageItem();
            note.Save($@"{fileName}.msg", NoteSaveFormat.Msg);
            break;
        // A Task item. Can be converted to MapiTask.
        // Save in MSG format.
        case MapiItemType.Task:
            var task = (MapiTask)msg.ToMapiMessageItem();
            task.Save($@"{fileName}.msg", TaskSaveFormat.Msg);
            break;
    }
}

IPM.Document for DocumentItem, which can be ANY kind of file, according to MS, even executables, just please advise when extracting storages, how to save such files with their original name/extension?

foreach (var messageInfo in folder.EnumerateMessages())
{
    var msg = pst.ExtractMessage(messageInfo);

    if (messageInfo.MessageClass == "IPM.Document")
    {
        var doc = pst.ExtractAttachments(messageInfo)[0];

        doc.Save(doc.LongFileName);
    }
}

The question is what format your devs recommend to save IPM.StickyNote / IPM.DistList and IPM.Activity/Journal ?

The most appropriate format for these items is MSG. In this case the items will be saved without loss of properties. For example, if you save IPM.StickyNote in html, it will lose the color property.

If you have a special save structure for Note/DistList/Journal please share the sample code?

Yes, it is MapiNote, MapiDistributionList, MapiJournal, respectively. See the example in the 1st point.