Hobby Chef

October, 2007 - Jive into Messaging world - Site Home - MSDN Blogs

Blog - Title

October, 2007

  • Jive into Messaging world

    HOWTO: OOM: Getting Primary SMTP Address from X500

    • 5 Comments

    Getting primary address from X500 address was always a pain when using OOM. Thank to these guys who realized this pain and built in this functionality in Outlook 2007 Object Model. I have figured out a way to get this value from within OOM for Outlook 2003 & below as well.

    How it works

    ============

    Uses native OOM support for 2007 & above else use the following workaround

    1) It will create a new contact item

    2) Set it's email address to the value passed by you, it could be X500 or SMTP address

    3) We will assign a random key to this contact item and save it in its Fullname to search it later

    4) Next we will save it to local contacts folder

    5) Outlook will try to resolve the email address & make AD call if required else take the Primary SMTP address from its cache and append it to Display name

    6) The display name will be something like this " ( email.address@server.com )"

    7) Now we need to parse the Display name and delete the contact from contacts folder

    8) Once the contact is deleted it will go to Deleted Items folder, after searching the contact using the unique random key generated in step 3

    9) We then need to delete it from Deleted Items folder as well, to clean all the traces

    DISCLAIMER: I have tested it only on 2003 & 2007, although logically it should work on all versions of Outlook.

    Function GetSMTPAddress(ByVal strAddress As String) 
    Dim oCon As ContactItem 
    Dim strKey As String 
    Dim oRec As Recipient 
    Dim strRet As String 
    
        'IF OUTLOOK VERSION IS >= 2007 THEN USES NATIVE OOM PROPERTIES AND METHODS 
    
        If CInt(Left(Application.Version, 2)) >= 12 Then 
            Set oRec = Session.CreateRecipient(strAddress) 
            If oRec.Resolve Then 
                strRet = oRec.AddressEntry.GetExchangeUser.PrimarySmtpAddress 
            End If 
        End If 
    
        If Not strRet = "" Then GoTo ReturnValue 
    
        'IF OUTLOOK VERSION IS < 2007 THEN USES LITTLE HACK 
    
        'How it works 
        '============ 
        '1) It will create a new contact item 
        '2) Set it's email address to the value passed by you, it could be X500,X400 or any type of email address stored in the AD 
        '3) We will assign a random key to this contact item and save it in its Fullname to search it later 
        '4) Next we will save it to local contacts folder 
        '5) Outlook will try to resolve the email address & make AD call if required else take the Primary SMTP address from its cache and append it to Display name 
        '6) The display name will be something like this " ( email.address@server.com )" 
        '7) Now we need to parse the Display name and delete the contact from contacts folder 
        '8) Once the contact is deleted it will go to Deleted Items folder, after searching the contact using the unique random key generated in step 3 
        '9) We then need to delete it from Deleted Items folder as well, to clean all the traces 
    
        Set oCon = Application.CreateItem(olContactItem) 
        oCon.Email1Address = strAddress 
        strKey = "_" & Replace(Rnd * 100000 & Format(Now, "DDMMYYYYHmmss"), ".", "") 
        oCon.FullName = strKey 
        oCon.Save 
        strRet = Trim(Replace(Replace(Replace(oCon.Email1DisplayName, "(", ""), ")", ""), strKey, "")) 
        oCon.Delete 
        Set oCon = Nothing 
    
        Set oCon = Session.GetDefaultFolder(olFolderDeletedItems).Items.Find("[Subject]=" & strKey) 
        If Not oCon Is Nothing Then oCon.Delete 
    
        ReturnValue: 
        GetSMTPAddress = strRet 
    End Function

    References:

    If you prefer then, you can do this with Exchange Web Services as well

    http://blogs.msdn.com/vikas/archive/2007/09/05/howto-ews-get-smtp-address-from-x500-address.aspx

    Keywords: GetExchangeUser , Exchange Web Services, Outlook Object Model, X500 to SMTP

  • Jive into Messaging world

    HOWTO: EWS: Add attachments to existing items on server

    • 4 Comments

    Forgot to add that attachment? Using exchange web service you can add it back to the item on the server. The code is simple and very easy to understand. It takes two parameters itemID – where attachment will be added, & strFileName – complete path to the local file.

    private bool AddAttachment(String itemID,String strFileName)

    {

    ExchangeServiceBinding esb = new ExchangeServiceBinding();

    esb.Credentials = new System.Net.NetworkCredential("username", "password", "domain");

    esb.Url = "http://exchange-cas-server/ews/exchange.asmx";

    //byte array to hold the attachment content

    byte[] bArray;

    //read the content from file into a byte array

    using (Stream fStream = new FileStream(strFileName, FileMode.Open))

    {

    int length;

    bArray = new byte[fStream.Length];

    fStream.Seek(0, SeekOrigin.Begin);

    length = fStream.Read(bArray, 0, (int)fStream.Length);

    }

    FileInfo fi = new FileInfo(strFileName);

    //create and populate the FileAttachment

    FileAttachmentType[] fata = new FileAttachmentType[1];

    fata[0] = new FileAttachmentType();

    fata[0].Name = fi.Name;

    fata[0].Content = bArray;

    //create the CreateAttachmentType object and make the CreateAttachment request

    CreateAttachmentType cat = new CreateAttachmentType();

    cat.ParentItemId = new ItemIdType();

    cat.ParentItemId.Id = itemID;

    cat.Attachments = fata;

    CreateAttachmentResponseType cart = esb.CreateAttachment(cat);

    ResponseMessageType rmt = ((ResponseMessageType)cart.ResponseMessages.Items[0]);

    if (rmt.ResponseClass == ResponseClassType.Success)

    return true;

    else

    return false;

    }

     

    Keywords: CreateAttachment, Exchange Web Services, add attachments

  • Jive into Messaging world

    HOWTO: EWS: Get LastModifiedTime for Items

    • 4 Comments

    So wondering where is LastModifiedTime?

    Exchange Web Services does not seem to give you the hint when the item was last modified. This property is not available in ItemType and expected to be available only after Exchange 2007 SP1.

    You can get the LastModifiedTime with the help of ExtendedProperty. I have created a sample to show you how.

    public DateTime GetLastModified(string itemID)

            {

    DateTime dtRet = new DateTime();

                ExchangeServiceBinding esb = new ExchangeServiceBinding();

                esb.AllowAutoRedirect = true;

                esb.Credentials = new System.Net.NetworkCredential("username", "password", "domain");

                esb.Url = "http://exchange-cas-server/ews/exchange.asmx";

                PathToExtendedFieldType[] ptufta = new PathToExtendedFieldType[1];

                ptufta[0] = new PathToExtendedFieldType();

                ptufta[0].PropertyTag = "0x3008"; //Property Tag for LastModifiedTime

                ptufta[0].PropertyType = MapiPropertyTypeType.SystemTime;

                ItemResponseShapeType irst = new ItemResponseShapeType();

                irst.BaseShape = DefaultShapeNamesType.IdOnly;

                irst.AdditionalProperties = ptufta;

                ItemIdType[] biita = new ItemIdType[1];

                biita[0] = new ItemIdType();

                biita[0].Id = itemID;

                //get the item

                GetItemType git = new GetItemType();

                git.ItemShape = irst;

                git.ItemIds = biita;

                GetItemResponseType girt = esb.GetItem(git);

                ItemType MsgItem = null;

                If (girt.ResponseMessages.Items[0].ResponseClass == ResponseClassType.Success)

                    MsgItem = ((ItemInfoResponseMessageType)girt.ResponseMessages.Items[0]).Items.Items[0];

               if (null != MsgItem)

    DateTime.TryParse(MsgItem.ExtendedProperty[0].Item.ToString(), out dtRet);

    return dtRet;

             

            }

     

    Keywords: GetLastModified, GetItem, Exchange Web Services, Exchange 2007

  • Jive into Messaging world

    HOWTO: EWS: Use GetAttachment to download attachments off Mail/Appointment

    • 15 Comments

    I have fallen for exchange web services. There are endless possibilities with exchange web services, and product group is still working to make it even better.

    Today I have created a neat sample to download attachments off Exchange Server

    Sample: DownloadAttachments

    Input Params: itemID , folder

    public void DownloadAttachments(string itemID,string folder)

    {

    ExchangeServiceBinding esb = new ExchangeServiceBinding();

    esb.AllowAutoRedirect = true;

    esb.Credentials = new System.Net.NetworkCredential("USERNAME", "PASSWORD", "DOMAIN");

    esb.Url = "http://your-cas-server/ews/exchange.asmx";

    //first we need to get the attachment IDs for the item so we will need to make a GetItem call first

    //specify the conetent that we want to retrieve

    PathToUnindexedFieldType[] ptufta = new PathToUnindexedFieldType[2];

    ptufta[0] = new PathToUnindexedFieldType();

    ptufta[0].FieldURI = UnindexedFieldURIType.itemAttachments;

    ptufta[1] = new PathToUnindexedFieldType();

    ptufta[1].FieldURI = UnindexedFieldURIType.itemHasAttachments;

    ItemResponseShapeType irst = new ItemResponseShapeType();

    irst.BaseShape = DefaultShapeNamesType.IdOnly;

    irst.AdditionalProperties = ptufta;

    ItemIdType[] biita = new ItemIdType[1];

    biita[0] = new ItemIdType();

    biita[0].Id = itemID;

    //get the items

    GetItemType git = new GetItemType();

    git.ItemShape = irst;

    git.ItemIds = biita;

    GetItemResponseType girt = esb.GetItem(git);

    if (girt.ResponseMessages.Items[0].ResponseClass != ResponseClassType.Success)

    return;

    //now that we have the attachment IDs let's request the atthacments and save them to disk

    ItemType MsgItem = ((ItemInfoResponseMessageType)girt.ResponseMessages.Items[0]).Items.Items[0];

    AttachmentResponseShapeType arst = null;

    AttachmentIdType[] aita = null;

    if (true == MsgItem.HasAttachments)

    {

    //create the attachment shape; we want the mime contnet just in case this is an message item so that we can save to disk

    arst = new AttachmentResponseShapeType();

    arst.IncludeMimeContent = true;

    arst.IncludeMimeContentSpecified = true;

    //create an array of attachment ids that we want to request

    aita = new AttachmentIdType[MsgItem.Attachments.Length];

    for (int i = 0; i < MsgItem.Attachments.Length; i++)

    {

    aita[i] = new AttachmentIdType();

    aita[i].Id = MsgItem.Attachments[i].AttachmentId.Id;

    }

    }

    //create a GetAttachment object for the GetAttachment operation

    GetAttachmentType gat = new GetAttachmentType();

    gat.AttachmentIds = aita;

    gat.AttachmentShape = arst;

    GetAttachmentResponseType gart = esb.GetAttachment(gat);

    //save each attachment to disk

    foreach (AttachmentInfoResponseMessageType Attachment in gart.ResponseMessages.Items)

    {

    switch (Attachment.Attachments[0].GetType().Name)

    {

    //attachments can be of type FileAttachmentType or ItemAttachmentType

    //so we need to figure out which type we have before we manipulate it

    case "FileAttachmentType":

    //save to disk

    FileAttachmentType TheFileAttachment = (FileAttachmentType)Attachment.Attachments[0];

    using (Stream FileToDisk = new FileStream(folder + @"\" + Attachment.Attachments[0].Name, FileMode.Create))

    {

    FileToDisk.Write(TheFileAttachment.Content, 0,

    TheFileAttachment.Content.Length);

    FileToDisk.Flush();

    FileToDisk.Close();

    }

    break;

    case "ItemAttachmentType":

    //save to disk

    ItemType TheItemAttachment = ((ItemAttachmentType)Attachment.Attachments[0]).Item;

    using (Stream FileToDisk = new FileStream(folder + @".\" + Attachment.Attachments[0].Name + ".eml", FileMode.Create))

    {

    byte[] ContentBytes = System.Convert.FromBase64String(TheItemAttachment.MimeContent.Value);

    FileToDisk.Write(ContentBytes, 0,

    ContentBytes.Length);

    FileToDisk.Flush();

    FileToDisk.Close();

    }

    break;

    default:

    break;

    }

    }

    }

     

    Keywords: GetAttachment, download attachments, exchange web services, exchange 2007

  • Jive into Messaging world

    EWS: BillingInformation is available only to TaskType

    • 1 Comments

    If you have ever tried to update BillingInformation of any item, other than tasks, using EWS then you may already know that BillingInformation is missing from Exchange Web Services object model and available only to TaskType. Although if you check the Outlook 2007 object model, it is available for MailItem, TaskItem, AppointmentItem, and to many others.

    It may be a bug or a design decision made by product group, I am still researching and trying to find out the answer behind this. But you may not want to wait that long and still want to update your BillingInformation using EWS.

    I have written the following sample code to update BillingInformation using EWS. I am using ExtendedProperty to update this named property

    CODE:

    //get the calendar folder ID

    DistinguishedFolderIdType[] dfita = new DistinguishedFolderIdType[1];

    dfita[0] = new DistinguishedFolderIdType();

    dfita[0].Id = DistinguishedFolderIdNameType.calendar;

    TargetFolderIdType tfidt = new TargetFolderIdType();

    tfidt.Item = dfita[0];

    //create the appt

    BodyType bt = new BodyType();

    bt.BodyType1 = BodyTypeType.Text;

    bt.Value = "This is the appointment Body";

    CalendarItemType[] calita = new CalendarItemType[1];

    calita[0] = new CalendarItemType();

    calita[0].ExtendedProperty = new ExtendedPropertyType[1];

    calita[0].ExtendedProperty[0] = new ExtendedPropertyType();

    calita[0].ExtendedProperty[0].ExtendedFieldURI = new PathToExtendedFieldType();

    calita[0].ExtendedProperty[0].ExtendedFieldURI.DistinguishedPropertySetId = DistinguishedPropertySetType.Common;

    calita[0].ExtendedProperty[0].ExtendedFieldURI.DistinguishedPropertySetIdSpecified = true;

    //NOTE: This PropertyID is equal to PropertyTag "0x8535" but you have to use PropertyID any not PropertyTag otherwise it will NOT work as expected and this billinginformation will not be visible via OOM or WebDAV, you have to specify it as Integer value in PropertyID field

    calita[0].ExtendedProperty[0].ExtendedFieldURI.PropertyId = 34101;

    calita[0].ExtendedProperty[0].ExtendedFieldURI.PropertyIdSpecified = true;

    calita[0].ExtendedProperty[0].ExtendedFieldURI.PropertyType = MapiPropertyTypeType.String;

    calita[0].ExtendedProperty[0].Item = "Billing Information Here";

    calita[0].Subject = txtSubject.Text;

    calita[0].Body = bt;

    calita[0].IsAllDayEvent = false;

    calita[0].Location = "Let's meet here";

    calita[0].ReminderIsSet = true;

    calita[0].ReminderMinutesBeforeStart = "60";

    calita[0].LegacyFreeBusyStatus = LegacyFreeBusyType.Busy;

    calita[0].Start = DateTime.Parse("15 October 2007");

    calita[0].StartSpecified = true;

    calita[0].End = DateTime.Parse("16 October 2007");

    calita[0].EndSpecified = true;

    NonEmptyArrayOfAllItemsType neaoait = new NonEmptyArrayOfAllItemsType();

    neaoait.Items = calita;

    CreateItemType cit = new CreateItemType();

    cit.SavedItemFolderId = tfidt;

    cit.SendMeetingInvitations =

    CalendarItemCreateOrDeleteOperationType.SendToNone;

    cit.SendMeetingInvitationsSpecified = true;

    cit.Items = neaoait;

    CreateItemResponseType cirt = esb.CreateItem(cit);

    …I will update this blog as soon as will get the answer to "Why BillingInformation is available only to TaskType?"

     

    Keywords: Exchange Web Services, Exchange 2007, BillingInformation not available for MessageType, TaskType

Page 1 of 1 (5 items)