usselite
usselite

Reputation: 816

VSTO recipient X400 address

Currently I am experiencing a rare issue, where the Outlook recipient object does not seem to contain the SMTP information of a user. Only the X400 information is available, very difficult to replicate this.

My code (input is AddressEntry addressEntry):

var exchangeUser = addressEntry.GetExchangeUser();

    if (exchangeUser != null)
    {
    //... get smtp exchangeUser.PrimarySmtpAddress
    }
    else
    {
    //... try find smtp by: 
                        var propertyEmailAttempt1 = addressEntry.PropertyAccessor.GetPropertySafe("0x39FE001F"); 
                        var propertyEmailAttempt2 = addressEntry.PropertyAccessor.GetPropertySafe("0x800F101F"); 
                        var propertyEmailAttempt3 = addressEntry.PropertyAccessor.GetPropertySafe("0x39FE001E");   
    
    }

In all instances, the properties return a null.

 public static dynamic GetPropertySafe(this Microsoft.Office.Interop.Outlook.PropertyAccessor propertyAccessor, string tag)
        {
            try
            {
                return propertyAccessor.GetProperty($"http://schemas.microsoft.com/mapi/proptag/{tag}");
            }
            catch
            {
                //Property is most likely not found
                return null;
            }
        }

In the last step, I just select addressEntry.Address, which returns the faulty address. The code does filter for the type EX. The recipient comes from a contact in Outlook, where the contact does have an SMTP address present, however is not available in model, only X400 address. The contact itself is present on same Exchange environment.

An idea I had was to do the following, resolve it manually like so:

Trace.WriteLine($"Recipient EX resolved: {recipient.Resolved} - {recipient.AddressEntry.Address}");
                // Is not resolved and does not contain @.
                if (!recipient.Resolved && recipient.AddressEntry?.Address?.Contains("@") == false)
                {
                    // Try first resolve.
                    recipient.Resolve();
                    
                    Trace.WriteLine($"Recipient EX second resolved: {recipient.Resolved} - {appOutlook.Session.Offline}");
                    // Now resolved? 
                    if (!recipient.Resolved && appOutlook.Session.Offline == false)
                    {
                        string address = $"{recipient.Address}";
                        // Create entry.
                        Recipient tempRecipient = appOutlook.Session.CreateRecipient(address);
                        tempRecipient.Resolve();

                        Trace.WriteLine($"TempRecipient EX resolved: {tempRecipient.Resolved} - {address}");
                        if (tempRecipient.Resolved)
                        {
                            var result = IsExchangeUser(tempRecipient.AddressEntry, type);
                            Marshal.ReleaseComObject(tempRecipient);
                            return result;
                        }
                    }
                }

However in my tests, with the X400 address I used for my tests, never resolve in the last step:

 Recipient tempRecipient = appOutlook.Session.CreateRecipient(address);
 tempRecipient.Resolve();

I am out of ideas on how to fix this. A possible suggestion on the internet was to use Outlook Redemption. However the question then remains can I fix this with Outlook redemption?

Upvotes: 0

Views: 29

Answers (1)

Dmitry Streblechenko
Dmitry Streblechenko

Reputation: 66286

A couple options:

  1. Given an EX type address, you can construct a valid address book entry id - if using Redemption is an option (I am its author) - use RDOSession.AddressBook.ExchangeAddressToEntryId. You can then open the address entry by its entry id (RDOSession.AddressBook.GetAddressEntryFromID) and read the SMTP address from RDOAddressEntry.SMTPAddress property.
  2. In this particular case, contacts created from Exchange entries do expose the SMTP address on the MAPI level (but not OOM). From Redemption, you can use RDOContactITem.Email1SmtpAddress/Email2SmtpAddress/Email3SmtpAddress properties. In OOM alone, you can use ContactItem.PropertyAccessor.GetProperty to read the http://schemas.microsoft.com/mapi/id/{00062004-0000-0000-C000-000000000046}/8084001F, http://schemas.microsoft.com/mapi/id/{00062004-0000-0000-C000-000000000046}/8094001F, and http://schemas.microsoft.com/mapi/id/{00062004-0000-0000-C000-000000000046}/80A4001F for addresses 1, 2, and 3 respectively.

Upvotes: 0

Related Questions