none
Getting the message "The sharing message is not supported." while sharing the calendar using ews managed api. RRS feed

  • Question

  •                                                                                              

      public void ShareCalendar(Calendar calendar)
            {           
                ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
                  service.Credentials = new NetworkCredential("user1", "password", "domain");
                service.Url = new Uri("https://sampleUrl/ews/exchange.asmx");

                try
                {
                    // Bind to the folder
                    //Folder folderStoreInfo;
                    //folderStoreInfo = Folder.Bind(service, calendar.ExchangeId);
                    //string EwsID = folderStoreInfo.Id.UniqueId;
                    string EwsID = calendar.FolderExchangeId;

                    // The value of folderidHex will be what we need to use for the FolderId in the xml file

                    AutodiscoverService autoDiscover = new AutodiscoverService(ExchangeVersion.Exchange2013);
                    autoDiscover.Credentials =  new NetworkCredential("user1", "password", "domain");
                    autoDiscover.RedirectionUrlValidationCallback = RedirectionUrlValidationCallback;


                    Dictionary<string, string> userSettings = GetUserSettings(autoDiscover);

                    string folderidHex = GetConvertedEWSIDinHex(service, EwsID, "user1@outlook.com");

                    string domainName = string.Empty;
                    string mailBoxServer = string.Empty;
                    string userName = string.Empty;
                    foreach (var item in userSettings)
                    {
                        switch (item.Key)
                        {
                            case "UserDN":
                                domainName = item.Value.ToString();
                                break;
                            case "InternalMailboxServer":
                                mailBoxServer = item.Value.ToString();
                                break;
                            case "UserDisplayName":
                                userName = item.Value.ToString();
                                break;
                        }
                    }

                    string entryId = GetIntiatorEntryID(domainName);

                    string mailboxId = GetInvitationMailboxId(mailBoxServer, domainName);


                    string sharedFilePath = CreateSharingMessageAttachment(folderidHex, userName, entryId, mailboxId, "user2@outlook.com", "calendar", calendar.FolderName);



                    // Create a new message
                    EmailMessage invitationRequest = new EmailMessage(service);
                    invitationRequest.Subject = "I'd like to share my calendar with you";
                    invitationRequest.Body = "Sent by Exchange Administrator on behalf of user";                
                    //invitationRequest.Culture = "en-US";
                    invitationRequest.Sensitivity = Sensitivity.Normal;

                    // Set a sharing specific property on the message
                    invitationRequest.ItemClass = "IPM.Sharing"; /* Constant Required Value [MS-ProtocolSpec] */

                    byte[] byteEntryId = HexStringToByteArray(entryId);

                    // This is the Guid of the Sharing Provider in Exchange, and it's value does not change
                    Guid binSharingProviderGuid = new Guid("{AEF00600-0000-0000-C000-000000000046}");

                    // Even though I don't think setting this property is mandatory, 
                    // it just seemed like the right thing to do and it works so I \
                    // ain't messin with it!                                        
                    byte[] byteSharingProviderGuid = binSharingProviderGuid.ToByteArray();

                    string strPRBODYHTML = "<html dir=\"ltr\">\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\r\n<meta name=\"GENERATOR\" content=\"MSHTML 8.00.7601.17514\">\r\n<style id=\"owaParaStyle\">P {\r\n   MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px \r\n}\r\n</style>\r\n</head>\r\n<body fPStyle=\"1\" ocsi=\"0\">\r\n<tt>\r\n<pre>SharedByUserDisplayName (SharedByUserSmtpAddress) has invited you to view his or her Microsoft Exchange Calendar.\r\n\r\nFor instructions on how to view shared folders on Exchange, see the following article:\r\n\r\nhttp://go.microsoft.com/fwlink/?LinkId=57561\r\n\r\n*~*~*~*~*~*~*~*~*~*\r\n\r\n</pre>\r\n</tt>\r\n<div>\r\n<div style=\"direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;\">this is a test message</div>\r\n</div>\r\n</body>\r\n</html>\r\n";

                    string strBODY = @"
    SharedByUserDisplayName (SharedByUserSmtpAddress) has invited you to view his or
    her Microsoft Exchange Calendar.

    For instructions on how to view shared folders on Exchange, see the
    following article:

    http://go.microsoft.com/fwlink/?LinkId=57561

    *~*~*~*~*~*~*~*~*~*


    test body

    ";
                    // Convert these to hex and binary equivelants to assign to their relevant
                    // extended properties
                    string hexPRBODYHTML = ConvertStringToHex(strPRBODYHTML);
                    byte[] binPRBODYHTML = HexStringToByteArray(hexPRBODYHTML);

                    Guid PropertySetSharing = Guid.Parse("00062040-0000-0000-C000-000000000046");//constant 
                    Guid PropertySetInternetHeaders = Guid.Parse("00020386-0000-0000-C000-000000000046");//constant

                    ExtendedPropertyDefinition PidLidSharingProviderGuidProperty = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A01, MapiPropertyType.CLSID);
                    ExtendedPropertyDefinition ConversationIdProperty = new ExtendedPropertyDefinition(0x3013, MapiPropertyType.Binary);


                    // Sharing Properties (in order of reference according to protocol examples in: [MS-OXSHARE])

                    // Additional Property Constraints
                    // [MS-OXSHARE] 2.2.5.2
                    ExtendedPropertyDefinition PidTagMessageClass = new ExtendedPropertyDefinition(0x001A, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.5.1
                    //ExtendedPropertyDefinition PidNameContentClass = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.InternetHeaders, "Content-Class", MapiPropertyType.String);
                    ExtendedPropertyDefinition PidNameContentClass = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "Content-class", MapiPropertyType.String);

                    // Common Message Object Properties               
                    // [MS-OXSHARE] 2.2.1
                    ExtendedPropertyDefinition PidTagNormalizedSubject = new ExtendedPropertyDefinition(0x0E1D, MapiPropertyType.String);
                    // The PidTagSubjectPrefix is a zero-length string, so I do not set it
                    // ExtendedPropertyDefinition PidTagSubjectPrefix = new ExtendedPropertyDefinition(0x003D, MapiPropertyType.String);

                    // Sharing Object Message Properties
                    // [MS-OXSHARE] 2.2.2.12
                    ExtendedPropertyDefinition PidLidSharingProviderGuid = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A01, MapiPropertyType.Binary);
                    // [MS-OXSHARE] 2.2.2.13
                    ExtendedPropertyDefinition PidNameXSharingProviderGuid = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Provider-GUID", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.14
                    ExtendedPropertyDefinition PidLidSharingProviderName = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A02, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.15           
                    ExtendedPropertyDefinition PidNameXSharingProviderName = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Provider-Name", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.16
                    ExtendedPropertyDefinition PidLidSharingProviderUrl = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A03, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.17
                    ExtendedPropertyDefinition PidNameXSharingProviderUrl = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Provider-URL", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.5
                    ExtendedPropertyDefinition PidLidSharingFlavor = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A18, MapiPropertyType.Integer);
                    // [MS-OXSHARE] 2.2.2.6
                    ExtendedPropertyDefinition PidNameXSharingFlavor = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Flavor", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.1
                    ExtendedPropertyDefinition PidLidSharingCapabilities = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A17, MapiPropertyType.Integer);
                    // [MS-OXSHARE] 2.2.2.2
                    ExtendedPropertyDefinition PidNameXSharingCapabilities = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Capabilities", MapiPropertyType.String);
                    // Sections 2.3 and 2.4 are also zero-length strings, so I won't set those either
                    // [MS-OXSHARE] 2.2.2.3
                    // ExtendedPropertyDefinition PidLidSharingConfigurationUrl = new   //ExtendedPropertyDefinition(PropertySetSharing, 0x8A24, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.4
                    //ExtendedPropertyDefinition PidNameXSharingConfigUrl = new //ExtendedPropertyDefinition(DefaultExtendedPropertySet.InternetHeaders, "X-Sharing-Config-Url", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.10
                    ExtendedPropertyDefinition PidLidSharingLocalType = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A14, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.11
                    ExtendedPropertyDefinition PidNameXSharingLocalType = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Local-Type", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.7
                    ExtendedPropertyDefinition PidLidSharingInitiatorEntryId = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A09, MapiPropertyType.Binary);
                    // [MS-OXSHARE] 2.2.2.8
                    ExtendedPropertyDefinition PidLidSharingInitiatorName = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A07, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.9
                    ExtendedPropertyDefinition PidLidSharingInitiatorSMTP = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A08, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.1
                    ExtendedPropertyDefinition PidLidSharingRemoteName = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A05, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.2 
                    ExtendedPropertyDefinition PidNameXSharingRemoteName = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Name", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.5 
                    ExtendedPropertyDefinition PidLidSharingRemoteType = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A1D, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.6 
                    ExtendedPropertyDefinition PidNameXSharingRemoteType = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Type", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.7 
                    ExtendedPropertyDefinition PidLidSharingRemoteUid = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A06, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.8 
                    ExtendedPropertyDefinition PidNameXSharingRemoteUid = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Uid", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.3
                    ExtendedPropertyDefinition PidLidSharingRemoteStoreUid = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A48, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.4
                    ExtendedPropertyDefinition PidNameXSharingRemoteStoreUid = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Store-Uid", MapiPropertyType.String);






                    //From troubleshooting I noticed I was missing
                    ExtendedPropertyDefinition PidTagPriority = new ExtendedPropertyDefinition(0x0026, MapiPropertyType.Integer);
                    ExtendedPropertyDefinition PidTagSensitivity = new ExtendedPropertyDefinition(0x0036, MapiPropertyType.Integer);
                    ExtendedPropertyDefinition PR_BODY_HTML = new ExtendedPropertyDefinition(0x1013, MapiPropertyType.Binary); //PR_BOD
                    ExtendedPropertyDefinition PR_BODY = new ExtendedPropertyDefinition(0x1000, MapiPropertyType.String);
                    ExtendedPropertyDefinition RecipientReassignmentProhibited = new ExtendedPropertyDefinition(0x002b, MapiPropertyType.Boolean);


                    // Section 2.2.1
                    invitationRequest.SetExtendedProperty(PidTagNormalizedSubject, "I'd like to share my calendar with you"); /* Constant Required Value [MS-OXSHARE] 2.2.1 */
                    //invitationRequest.SetExtendedProperty(PidTagSubjectPrefix, String.Empty); /* Constant Required Value [MS-OXSHARE] 2.2.1 */
                    // Section 2.2.2
                    invitationRequest.SetExtendedProperty(PidLidSharingCapabilities, 0x40220); /* value for Special Folders */
                    invitationRequest.SetExtendedProperty(PidNameXSharingCapabilities, "40220"); /* Test representation of SharingCapabilities value */
                    //invitationRequest.SetExtendedProperty(PidLidSharingConfigurationUrl, String.Empty); /* Zero-Length String [MS-OXSHARE] 2.2.2.3 */
                    //invitationRequest.SetExtendedProperty(PidNameXSharingConfigUrl, String.Empty); /* Zero-Length String [MS-OXSHARE] 2.2.2.4 */
                    invitationRequest.SetExtendedProperty(PidLidSharingFlavor, 0x20310); /* Indicates Invitation for a special folder [MS-OXSHARE] 2.2.2.5 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingFlavor, "20310"); /* Text representation of SharingFlavor value [MS-OXSHARE] 2.2.2.6 */
                    invitationRequest.SetExtendedProperty(PidLidSharingInitiatorEntryId, byteEntryId); /* Value from the Initiator/EntryId value in the Sharing Message attachment .xml document */
                    invitationRequest.SetExtendedProperty(PidLidSharingInitiatorSMTP, "user1@outlook.com"); /* Value from Initiator/Smtp Address in the Sharing message attachment .xml document */
                    invitationRequest.SetExtendedProperty(PidLidSharingInitiatorName, "User1"); /* Value from Initiator/Name Address in the Sharing message attachment .xml document */
                    invitationRequest.SetExtendedProperty(PidLidSharingLocalType, "IPF.Appointment"); /* MUST be set to PidTagContainerClass of folder to be shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingLocalType, "IPF.Appointment"); /* MUST be set to same value as PidLidSharingLocalType */
                    invitationRequest.SetExtendedProperty(PidLidSharingProviderGuid, byteSharingProviderGuid); /* Constant Required Value [MS-OXSHARE] 2.2.2.12 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingProviderGuid, "AEF0060000000000C000000000000046"); /* Constant Required Value [MS-OXSHARE] 2.2.2.13 */
                    invitationRequest.SetExtendedProperty(PidLidSharingProviderName, "Microsoft Exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.14 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingProviderName, "Microsoft Exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.15] */
                    invitationRequest.SetExtendedProperty(PidLidSharingProviderUrl, "http://www.microsoft.com/exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.16 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingProviderUrl, "http://www.microsoft.com/exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.17 */
                    // Section 2.2.3
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteName, calendar.FolderName); /* MUST be set to PidTagDisplayName of the folder being shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteName, calendar.FolderName); /* MUST be set to same value as PidLidSharingRemoteName */
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteStoreUid, mailboxId); /* Must be set to PidTagStoreEntryId of the folder being shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteStoreUid, mailboxId); /* MUST be set to same value as PidLidSharingRemoteStoreUid */
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteType, "IPF.Appointment"); /* Constant Required Value [MS-OXSHARE] 2.2.3.5 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteType, "IPF.Appointment"); /* Constant Required Value [MS-OXSHARE] 2.2.3.6 */
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteUid, folderidHex); /* MUST be set to PidTagEntryId of folder being shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteUid, folderidHex); /* Must be set to same value as PidLidSharingRemoteUid */
                    // Section 2.2.5
                    invitationRequest.SetExtendedProperty(PidNameContentClass, "Sharing"); /* Constant Required Value [MS-ProtocolSpec] */
                    invitationRequest.SetExtendedProperty(PidTagMessageClass, "IPM.Sharing"); /* Constant Required Value [MS-ProtocolSpec] */


                    // ********* ADDITIONAL MAPPED PROPERTIES IM FINDING AS I TROUBLESHOOT ********************** //
                    invitationRequest.SetExtendedProperty(PidTagPriority, 0); /* From troubleshooting I'm just trying to match up values that were missing */
                    invitationRequest.SetExtendedProperty(PidTagSensitivity, 0); /* From troubleshooting as well */
                    invitationRequest.SetExtendedProperty(PR_BODY_HTML, binPRBODYHTML); /* From troubleshooting OWA error pointing to serializing HTML failing */
                    invitationRequest.SetExtendedProperty(PR_BODY, strBODY);
                    invitationRequest.SetExtendedProperty(RecipientReassignmentProhibited, true); /* Because it seemed like a good idea */

                    // Add a file attachment by using a stream
                    // We need to do the following in order to prevent 3 extra bytes from being prepended to the attachment
                    string sharMetadata = File.ReadAllText(sharedFilePath, Encoding.ASCII);
                    byte[] fileContents;
                    UTF8Encoding encoding = new System.Text.UTF8Encoding();
                    fileContents = encoding.GetBytes(sharMetadata);
                    //fileContents = File.ReadAllBytes(sharedFilePath);

                    //// fileContents is a Stream object that represents the content of the file to attach.
                    invitationRequest.Attachments.AddFileAttachment("sharing_metadata.xml", fileContents);

                    ////invitationRequest.Attachments.AddFileAttachment(sharedFilePath);
                    //// This is where we set those "special" headers and other pertinent
                    //// information I noted in Part 1 of this series...
                    //Attachment thisAttachment = invitationRequest.Attachments[0];
                    //thisAttachment.ContentType = "application/x-sharing-metadata-xml";
                    //thisAttachment.Name = "sharing_metadata.xml";
                    //thisAttachment.IsInline = false;

                    // Add recipient info and send message
                    invitationRequest.ToRecipients.Add(new EmailAddress() { Address = "user2@outlook.com" });


                    invitationRequest.SendAndSaveCopy();

                    // I always end my methods by returning the EWS 
                    // impersonated user to null to clean up
                    service.ImpersonatedUserId = null;

                }
                catch (Exception ex)
                {

                }
            }

            public String GetConvertedEWSIDinHex(ExchangeService esb, String sID, String strSMTPAdd)
            {
                // Create a request to convert identifiers.
                AlternateId objAltID = new AlternateId();
                objAltID.Format = IdFormat.EwsId;
                objAltID.Mailbox = strSMTPAdd;
                objAltID.UniqueId = sID;

                //Convert  PR_ENTRYID identifier format to an EWS identifier.
                AlternateIdBase objAltIDBase = esb.ConvertId(objAltID, IdFormat.HexEntryId);
                AlternateId objAltIDResp = (AlternateId)objAltIDBase;
                return objAltIDResp.UniqueId.ToString();
            }

            public String GetInvitationMailboxId(string mailBoxServer, string domainName)
            {
                ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
                service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "user1@outlook.com");
                // Generate The Store Entry Id for the impersonated user
                StringBuilder MailboxIDPointer = new StringBuilder();          
                string fqdn = mailBoxServer;
                string legacyDN = domainName;


                MailboxIDPointer.Append("00000000"); /* Flags */
                MailboxIDPointer.Append("38A1BB1005E5101AA1BB08002B2A56C2"); /* ProviderUID */
                MailboxIDPointer.Append("00"); /* Version */
                MailboxIDPointer.Append("00"); /* Flag */
                MailboxIDPointer.Append("454D534D44422E444C4C00000000"); /* DLLFileName */
                MailboxIDPointer.Append("00000000"); /* Wrapped Flags */
                MailboxIDPointer.Append("1B55FA20AA6611CD9BC800AA002FC45A"); /* WrappedProvider UID (Mailbox Store Object) */
                MailboxIDPointer.Append("0C000000"); /* Wrapped Type (Mailbox Store) */
                MailboxIDPointer.Append(ConvertStringToHex(fqdn)); /* ServerShortname (FQDN) */
                MailboxIDPointer.Append("00"); /* termination bit */
                MailboxIDPointer.Append(ConvertStringToHex(legacyDN)); /* Returns the userDN of the impersonated user */
                MailboxIDPointer.Append("00"); /* terminator bit */


                service.ImpersonatedUserId = null;
                return MailboxIDPointer.ToString();

            }

            static bool RedirectionUrlValidationCallback(String redirectionUrl)
            {
                bool redirectionValidated = false;
                if (redirectionUrl.Equals("https://SampleUrl/autodiscover/autodiscover.xml"))          
                {
                    redirectionValidated = true;
                }
                return redirectionValidated;
            }

            public String GetIntiatorEntryID(string domainName)
            {
                String result = String.Empty;

                //// Bind to EWS
                //ExchangeService service = ExchangeConnection.ExchangeService();
                //service.ImpersonatedUserId =
                //new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "user1@outlook.com");

                //// Get LegacyDN Using the function above this one 

                string sharedByLegacyDN = domainName;
                // A conversion function from earlier
                string legacyDNinHex = ConvertStringToHex(sharedByLegacyDN);



                StringBuilder addBookEntryId = new StringBuilder();



                addBookEntryId.Append("00000000"); /* Flags */
                addBookEntryId.Append("DCA740C8C042101AB4B908002B2FE182"); /* ProviderUID */
                addBookEntryId.Append("01000000"); /* Version */
                addBookEntryId.Append("00000000"); /* Type - 00 00 00 00  = Local Mail User */
                addBookEntryId.Append(legacyDNinHex); /* Returns the userDN of the impersonated user */
                addBookEntryId.Append("00"); /* terminator bit */


                result = addBookEntryId.ToString();
                //service.ImpersonatedUserId = null;
                return result;
            }

            public string ConvertStringToHex(string input)
            {
                // Take our input and break it into an array
                char[] arrInput = input.ToCharArray();
                String result = String.Empty;

                // For each set of characters
                foreach (char element in arrInput)
                {               
                    if (String.IsNullOrEmpty(result))
                    {
                        result = String.Format("{0:X2}", Convert.ToUInt16(element)).ToString();
                    }
                    else
                    {
                        result += String.Format("{0:X2}", Convert.ToUInt16(element)).ToString();
                    }

                }
                return result.ToString();
            }

     public string CreateSharingMessageAttachment(string folderid, string userSharing, string userSharingEntryID, string invitationMailboxID, string userSharedTo, string dataType, string calendarName)
            {
                XmlDocument sharedMetadataXML = new XmlDocument();
                string sharedMetaDataFilePath = string.Empty;
                try
                {

                    // Create a String that contains our new sharing_metadata.xml file
                    StringBuilder metadataString = new StringBuilder("<?xml version=\"1.0\"?>");              
                    metadataString.Append("<SharingMessage xmlns=\"http://schemas.microsoft.com/sharing/2008\">");
                    metadataString.Append("<DataType>" + dataType + "</DataType>");
                    metadataString.Append("<Initiator>");
                    metadataString.Append("<Name>" + userSharing + "</Name>");
                    metadataString.Append("<SmtpAddress>" + "Shyam@ProConstructor.com" + "</SmtpAddress><EntryId>" + userSharingEntryID.Trim());
                    metadataString.Append("</EntryId>");
                    metadataString.Append("</Initiator>");
                    metadataString.Append("<Invitation>");
                    metadataString.Append("<Title>" + calendarName + "</Title>");
                    metadataString.Append("<Providers>");
                    metadataString.Append("<Provider Type=\"ms-exchange-internal\" TargetRecipients=\"" + userSharedTo + "\">");
                    metadataString.Append("<FolderId xmlns=\"http://schemas.microsoft.com/exchange/sharing/2008\">");
                    metadataString.Append(folderid);
                    metadataString.Append("</FolderId>");
                    metadataString.Append("<MailboxId xmlns=\"http://schemas.microsoft.com/exchange/sharing/2008\">");
                    metadataString.Append(invitationMailboxID);
                    metadataString.Append("</MailboxId>");
                    metadataString.Append("</Provider>");
                    metadataString.Append("</Providers>");
                    metadataString.Append("</Invitation>");
                    metadataString.Append("</SharingMessage>");
                   
                    sharedMetadataXML.LoadXml(metadataString.ToString());
                 
                    string tempPath = System.IO.Path.GetTempPath();

                    sharedMetaDataFilePath = tempPath + "sharing_metadata.xml";
                    sharedMetadataXML.Save(sharedMetaDataFilePath);

                }
                catch (Exception eg)
                {
                    throw eg;               
                }
                return sharedMetaDataFilePath;
            }



            public Dictionary<string, string> GetUserSettings(AutodiscoverService autodiscoverService)
            {


                GetUserSettingsResponse userresponse = autodiscoverService.GetUserSettings(
                    "user1@outlook.com",
                    UserSettingName.UserDisplayName,
                    UserSettingName.InternalMailboxServerDN,
                    UserSettingName.UserDN
                );

                Dictionary<string, string> myUserSettings = new Dictionary<string, string>();

                foreach (KeyValuePair<UserSettingName, Object> usersetting in userresponse.Settings)
                {

                    if (usersetting.Key.ToString() == "InternalMailboxServerDN")
                    {
                        int lastIndexOfEqual = usersetting.Value.ToString().LastIndexOf("=");
                        string subString = usersetting.Value.ToString().Substring(lastIndexOfEqual + 1);

                        string value = subString;
                        myUserSettings.Add("InternalMailboxServer", value.ToString());

                    }
                    if (usersetting.Key.ToString() == "UserDisplayName")
                    {
                        string[] arrResult = usersetting.Value.ToString().Split('.');

                        myUserSettings.Add("UserDisplayName", arrResult[0].ToString());

                    }
                    if (usersetting.Key.ToString() == "UserDN")
                    {
                        string[] arrResult = usersetting.Value.ToString().Split('.');

                        myUserSettings.Add("UserDN", arrResult[0].ToString());

                    }
                }

                return myUserSettings;
            }

            private static byte[] HexStringToByteArray(string input)
            {

                byte[] Bytes;

                int ByteLength;

                string HexValue = "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9|||||||\xA\xB\xC\xD\xE\xF";

                ByteLength = input.Length / 2;

                Bytes = new byte[ByteLength];

                for (int x = 0, i = 0; i < input.Length; i += 2, x += 1)
                {
                    Bytes[x] = (byte)(HexValue[Char.ToUpper(input[i + 0]) - '0'] << 4);
                    Bytes[x] |= (byte)(HexValue[Char.ToUpper(input[i + 1]) - '0']);
                }

                return Bytes;
            }



    • Edited by Shyam0007 Thursday, March 12, 2015 9:22 AM
    Wednesday, March 11, 2015 10:31 AM

All replies

  • Hi,

    I'm trying to share a calendar through ews managed api v.2 and using exchange 2013 version.

    i'm preparing a shared calendar and providing values to extended properties .

    Here comes the problem when i'm trying to send the sharing request(email message) 

    The following is code snippet.

                                                                                                                                                   

      public void ShareCalendar(Calendar calendar)
            {           
                ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
                  service.Credentials = new NetworkCredential("user1", "password", "domain");
                service.Url = new Uri("https://sampleUrl/ews/exchange.asmx");

                try
                {
                    // Bind to the folder
                    //Folder folderStoreInfo;
                    //folderStoreInfo = Folder.Bind(service, calendar.ExchangeId);
                    //string EwsID = folderStoreInfo.Id.UniqueId;
                    string EwsID = calendar.FolderExchangeId;

                    // The value of folderidHex will be what we need to use for the FolderId in the xml file

                    AutodiscoverService autoDiscover = new AutodiscoverService(ExchangeVersion.Exchange2013);
                    autoDiscover.Credentials =  new NetworkCredential("user1", "password", "domain");
                    autoDiscover.RedirectionUrlValidationCallback = RedirectionUrlValidationCallback;


                    Dictionary<string, string> userSettings = GetUserSettings(autoDiscover);

                    string folderidHex = GetConvertedEWSIDinHex(service, EwsID, "user1@outlook.com");

                    string domainName = string.Empty;
                    string mailBoxServer = string.Empty;
                    string userName = string.Empty;
                    foreach (var item in userSettings)
                    {
                        switch (item.Key)
                        {
                            case "UserDN":
                                domainName = item.Value.ToString();
                                break;
                            case "InternalMailboxServer":
                                mailBoxServer = item.Value.ToString();
                                break;
                            case "UserDisplayName":
                                userName = item.Value.ToString();
                                break;
                        }
                    }

                    string entryId = GetIntiatorEntryID(domainName);

                    string mailboxId = GetInvitationMailboxId(mailBoxServer, domainName);


                    string sharedFilePath = CreateSharingMessageAttachment(folderidHex, userName, entryId, mailboxId, "user2@outlook.com", "calendar", calendar.FolderName);



                    // Create a new message
                    EmailMessage invitationRequest = new EmailMessage(service);
                    invitationRequest.Subject = "I'd like to share my calendar with you";
                    invitationRequest.Body = "Sent by Exchange Administrator on behalf of user";                
                    //invitationRequest.Culture = "en-US";
                    invitationRequest.Sensitivity = Sensitivity.Normal;

                    // Set a sharing specific property on the message
                    invitationRequest.ItemClass = "IPM.Sharing"; /* Constant Required Value [MS-ProtocolSpec] */

                    byte[] byteEntryId = HexStringToByteArray(entryId);

                    // This is the Guid of the Sharing Provider in Exchange, and it's value does not change
                    Guid binSharingProviderGuid = new Guid("{AEF00600-0000-0000-C000-000000000046}");

                    // Even though I don't think setting this property is mandatory, 
                    // it just seemed like the right thing to do and it works so I \
                    // ain't messin with it!                                        
                    byte[] byteSharingProviderGuid = binSharingProviderGuid.ToByteArray();

                    string strPRBODYHTML = "<html dir=\"ltr\">\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\r\n<meta name=\"GENERATOR\" content=\"MSHTML 8.00.7601.17514\">\r\n<style id=\"owaParaStyle\">P {\r\n   MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px \r\n}\r\n</style>\r\n</head>\r\n<body fPStyle=\"1\" ocsi=\"0\">\r\n<tt>\r\n<pre>SharedByUserDisplayName (SharedByUserSmtpAddress) has invited you to view his or her Microsoft Exchange Calendar.\r\n\r\nFor instructions on how to view shared folders on Exchange, see the following article:\r\n\r\nhttp://go.microsoft.com/fwlink/?LinkId=57561\r\n\r\n*~*~*~*~*~*~*~*~*~*\r\n\r\n</pre>\r\n</tt>\r\n<div>\r\n<div style=\"direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;\">this is a test message</div>\r\n</div>\r\n</body>\r\n</html>\r\n";

                    string strBODY = @"
    SharedByUserDisplayName (SharedByUserSmtpAddress) has invited you to view his or
    her Microsoft Exchange Calendar.

    For instructions on how to view shared folders on Exchange, see the
    following article:

    http://go.microsoft.com/fwlink/?LinkId=57561

    *~*~*~*~*~*~*~*~*~*


    test body

    ";
                    // Convert these to hex and binary equivelants to assign to their relevant
                    // extended properties
                    string hexPRBODYHTML = ConvertStringToHex(strPRBODYHTML);
                    byte[] binPRBODYHTML = HexStringToByteArray(hexPRBODYHTML);

                    Guid PropertySetSharing = Guid.Parse("00062040-0000-0000-C000-000000000046");//constant 
                    Guid PropertySetInternetHeaders = Guid.Parse("00020386-0000-0000-C000-000000000046");//constant

                    ExtendedPropertyDefinition PidLidSharingProviderGuidProperty = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A01, MapiPropertyType.CLSID);
                    ExtendedPropertyDefinition ConversationIdProperty = new ExtendedPropertyDefinition(0x3013, MapiPropertyType.Binary);


                    // Sharing Properties (in order of reference according to protocol examples in: [MS-OXSHARE])

                    // Additional Property Constraints
                    // [MS-OXSHARE] 2.2.5.2
                    ExtendedPropertyDefinition PidTagMessageClass = new ExtendedPropertyDefinition(0x001A, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.5.1
                    //ExtendedPropertyDefinition PidNameContentClass = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.InternetHeaders, "Content-Class", MapiPropertyType.String);
                    ExtendedPropertyDefinition PidNameContentClass = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "Content-class", MapiPropertyType.String);

                    // Common Message Object Properties               
                    // [MS-OXSHARE] 2.2.1
                    ExtendedPropertyDefinition PidTagNormalizedSubject = new ExtendedPropertyDefinition(0x0E1D, MapiPropertyType.String);
                    // The PidTagSubjectPrefix is a zero-length string, so I do not set it
                    // ExtendedPropertyDefinition PidTagSubjectPrefix = new ExtendedPropertyDefinition(0x003D, MapiPropertyType.String);

                    // Sharing Object Message Properties
                    // [MS-OXSHARE] 2.2.2.12
                    ExtendedPropertyDefinition PidLidSharingProviderGuid = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A01, MapiPropertyType.Binary);
                    // [MS-OXSHARE] 2.2.2.13
                    ExtendedPropertyDefinition PidNameXSharingProviderGuid = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Provider-GUID", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.14
                    ExtendedPropertyDefinition PidLidSharingProviderName = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A02, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.15           
                    ExtendedPropertyDefinition PidNameXSharingProviderName = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Provider-Name", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.16
                    ExtendedPropertyDefinition PidLidSharingProviderUrl = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A03, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.17
                    ExtendedPropertyDefinition PidNameXSharingProviderUrl = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Provider-URL", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.5
                    ExtendedPropertyDefinition PidLidSharingFlavor = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A18, MapiPropertyType.Integer);
                    // [MS-OXSHARE] 2.2.2.6
                    ExtendedPropertyDefinition PidNameXSharingFlavor = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Flavor", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.1
                    ExtendedPropertyDefinition PidLidSharingCapabilities = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A17, MapiPropertyType.Integer);
                    // [MS-OXSHARE] 2.2.2.2
                    ExtendedPropertyDefinition PidNameXSharingCapabilities = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Capabilities", MapiPropertyType.String);
                    // Sections 2.3 and 2.4 are also zero-length strings, so I won't set those either
                    // [MS-OXSHARE] 2.2.2.3
                    // ExtendedPropertyDefinition PidLidSharingConfigurationUrl = new   //ExtendedPropertyDefinition(PropertySetSharing, 0x8A24, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.4
                    //ExtendedPropertyDefinition PidNameXSharingConfigUrl = new //ExtendedPropertyDefinition(DefaultExtendedPropertySet.InternetHeaders, "X-Sharing-Config-Url", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.10
                    ExtendedPropertyDefinition PidLidSharingLocalType = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A14, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.11
                    ExtendedPropertyDefinition PidNameXSharingLocalType = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Local-Type", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.7
                    ExtendedPropertyDefinition PidLidSharingInitiatorEntryId = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A09, MapiPropertyType.Binary);
                    // [MS-OXSHARE] 2.2.2.8
                    ExtendedPropertyDefinition PidLidSharingInitiatorName = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A07, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.9
                    ExtendedPropertyDefinition PidLidSharingInitiatorSMTP = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A08, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.1
                    ExtendedPropertyDefinition PidLidSharingRemoteName = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A05, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.2 
                    ExtendedPropertyDefinition PidNameXSharingRemoteName = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Name", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.5 
                    ExtendedPropertyDefinition PidLidSharingRemoteType = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A1D, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.6 
                    ExtendedPropertyDefinition PidNameXSharingRemoteType = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Type", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.7 
                    ExtendedPropertyDefinition PidLidSharingRemoteUid = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A06, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.8 
                    ExtendedPropertyDefinition PidNameXSharingRemoteUid = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Uid", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.3
                    ExtendedPropertyDefinition PidLidSharingRemoteStoreUid = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A48, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.4
                    ExtendedPropertyDefinition PidNameXSharingRemoteStoreUid = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Store-Uid", MapiPropertyType.String);






                    //From troubleshooting I noticed I was missing
                    ExtendedPropertyDefinition PidTagPriority = new ExtendedPropertyDefinition(0x0026, MapiPropertyType.Integer);
                    ExtendedPropertyDefinition PidTagSensitivity = new ExtendedPropertyDefinition(0x0036, MapiPropertyType.Integer);
                    ExtendedPropertyDefinition PR_BODY_HTML = new ExtendedPropertyDefinition(0x1013, MapiPropertyType.Binary); //PR_BOD
                    ExtendedPropertyDefinition PR_BODY = new ExtendedPropertyDefinition(0x1000, MapiPropertyType.String);
                    ExtendedPropertyDefinition RecipientReassignmentProhibited = new ExtendedPropertyDefinition(0x002b, MapiPropertyType.Boolean);


                    // Section 2.2.1
                    invitationRequest.SetExtendedProperty(PidTagNormalizedSubject, "I'd like to share my calendar with you"); /* Constant Required Value [MS-OXSHARE] 2.2.1 */
                    //invitationRequest.SetExtendedProperty(PidTagSubjectPrefix, String.Empty); /* Constant Required Value [MS-OXSHARE] 2.2.1 */
                    // Section 2.2.2
                    invitationRequest.SetExtendedProperty(PidLidSharingCapabilities, 0x40220); /* value for Special Folders */
                    invitationRequest.SetExtendedProperty(PidNameXSharingCapabilities, "40220"); /* Test representation of SharingCapabilities value */
                    //invitationRequest.SetExtendedProperty(PidLidSharingConfigurationUrl, String.Empty); /* Zero-Length String [MS-OXSHARE] 2.2.2.3 */
                    //invitationRequest.SetExtendedProperty(PidNameXSharingConfigUrl, String.Empty); /* Zero-Length String [MS-OXSHARE] 2.2.2.4 */
                    invitationRequest.SetExtendedProperty(PidLidSharingFlavor, 0x20310); /* Indicates Invitation for a special folder [MS-OXSHARE] 2.2.2.5 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingFlavor, "20310"); /* Text representation of SharingFlavor value [MS-OXSHARE] 2.2.2.6 */
                    invitationRequest.SetExtendedProperty(PidLidSharingInitiatorEntryId, byteEntryId); /* Value from the Initiator/EntryId value in the Sharing Message attachment .xml document */
                    invitationRequest.SetExtendedProperty(PidLidSharingInitiatorSMTP, "user1@outlook.com"); /* Value from Initiator/Smtp Address in the Sharing message attachment .xml document */
                    invitationRequest.SetExtendedProperty(PidLidSharingInitiatorName, "User1"); /* Value from Initiator/Name Address in the Sharing message attachment .xml document */
                    invitationRequest.SetExtendedProperty(PidLidSharingLocalType, "IPF.Appointment"); /* MUST be set to PidTagContainerClass of folder to be shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingLocalType, "IPF.Appointment"); /* MUST be set to same value as PidLidSharingLocalType */
                    invitationRequest.SetExtendedProperty(PidLidSharingProviderGuid, byteSharingProviderGuid); /* Constant Required Value [MS-OXSHARE] 2.2.2.12 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingProviderGuid, "AEF0060000000000C000000000000046"); /* Constant Required Value [MS-OXSHARE] 2.2.2.13 */
                    invitationRequest.SetExtendedProperty(PidLidSharingProviderName, "Microsoft Exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.14 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingProviderName, "Microsoft Exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.15] */
                    invitationRequest.SetExtendedProperty(PidLidSharingProviderUrl, "http://www.microsoft.com/exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.16 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingProviderUrl, "http://www.microsoft.com/exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.17 */
                    // Section 2.2.3
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteName, calendar.FolderName); /* MUST be set to PidTagDisplayName of the folder being shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteName, calendar.FolderName); /* MUST be set to same value as PidLidSharingRemoteName */
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteStoreUid, mailboxId); /* Must be set to PidTagStoreEntryId of the folder being shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteStoreUid, mailboxId); /* MUST be set to same value as PidLidSharingRemoteStoreUid */
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteType, "IPF.Appointment"); /* Constant Required Value [MS-OXSHARE] 2.2.3.5 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteType, "IPF.Appointment"); /* Constant Required Value [MS-OXSHARE] 2.2.3.6 */
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteUid, folderidHex); /* MUST be set to PidTagEntryId of folder being shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteUid, folderidHex); /* Must be set to same value as PidLidSharingRemoteUid */
                    // Section 2.2.5
                    invitationRequest.SetExtendedProperty(PidNameContentClass, "Sharing"); /* Constant Required Value [MS-ProtocolSpec] */
                    invitationRequest.SetExtendedProperty(PidTagMessageClass, "IPM.Sharing"); /* Constant Required Value [MS-ProtocolSpec] */


                    // ********* ADDITIONAL MAPPED PROPERTIES IM FINDING AS I TROUBLESHOOT ********************** //
                    invitationRequest.SetExtendedProperty(PidTagPriority, 0); /* From troubleshooting I'm just trying to match up values that were missing */
                    invitationRequest.SetExtendedProperty(PidTagSensitivity, 0); /* From troubleshooting as well */
                    invitationRequest.SetExtendedProperty(PR_BODY_HTML, binPRBODYHTML); /* From troubleshooting OWA error pointing to serializing HTML failing */
                    invitationRequest.SetExtendedProperty(PR_BODY, strBODY);
                    invitationRequest.SetExtendedProperty(RecipientReassignmentProhibited, true); /* Because it seemed like a good idea */

                    // Add a file attachment by using a stream
                    // We need to do the following in order to prevent 3 extra bytes from being prepended to the attachment
                    string sharMetadata = File.ReadAllText(sharedFilePath, Encoding.ASCII);
                    byte[] fileContents;
                    UTF8Encoding encoding = new System.Text.UTF8Encoding();
                    fileContents = encoding.GetBytes(sharMetadata);
                    //fileContents = File.ReadAllBytes(sharedFilePath);

                    //// fileContents is a Stream object that represents the content of the file to attach.
                    invitationRequest.Attachments.AddFileAttachment("sharing_metadata.xml", fileContents);

                    ////invitationRequest.Attachments.AddFileAttachment(sharedFilePath);
                    //// This is where we set those "special" headers and other pertinent
                    //// information I noted in Part 1 of this series...
                    //Attachment thisAttachment = invitationRequest.Attachments[0];
                    //thisAttachment.ContentType = "application/x-sharing-metadata-xml";
                    //thisAttachment.Name = "sharing_metadata.xml";
                    //thisAttachment.IsInline = false;

                    // Add recipient info and send message
                    invitationRequest.ToRecipients.Add(new EmailAddress() { Address = "user2@outlook.com" });


                    invitationRequest.SendAndSaveCopy();

                    // I always end my methods by returning the EWS 
                    // impersonated user to null to clean up
                    service.ImpersonatedUserId = null;

                }
                catch (Exception ex)
                {

                }
            }

            public String GetConvertedEWSIDinHex(ExchangeService esb, String sID, String strSMTPAdd)
            {
                // Create a request to convert identifiers.
                AlternateId objAltID = new AlternateId();
                objAltID.Format = IdFormat.EwsId;
                objAltID.Mailbox = strSMTPAdd;
                objAltID.UniqueId = sID;

                //Convert  PR_ENTRYID identifier format to an EWS identifier.
                AlternateIdBase objAltIDBase = esb.ConvertId(objAltID, IdFormat.HexEntryId);
                AlternateId objAltIDResp = (AlternateId)objAltIDBase;
                return objAltIDResp.UniqueId.ToString();
            }

            public String GetInvitationMailboxId(string mailBoxServer, string domainName)
            {
                ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
                service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "user1@outlook.com");
                // Generate The Store Entry Id for the impersonated user
                StringBuilder MailboxIDPointer = new StringBuilder();          
                string fqdn = mailBoxServer;
                string legacyDN = domainName;


                MailboxIDPointer.Append("00000000"); /* Flags */
                MailboxIDPointer.Append("38A1BB1005E5101AA1BB08002B2A56C2"); /* ProviderUID */
                MailboxIDPointer.Append("00"); /* Version */
                MailboxIDPointer.Append("00"); /* Flag */
                MailboxIDPointer.Append("454D534D44422E444C4C00000000"); /* DLLFileName */
                MailboxIDPointer.Append("00000000"); /* Wrapped Flags */
                MailboxIDPointer.Append("1B55FA20AA6611CD9BC800AA002FC45A"); /* WrappedProvider UID (Mailbox Store Object) */
                MailboxIDPointer.Append("0C000000"); /* Wrapped Type (Mailbox Store) */
                MailboxIDPointer.Append(ConvertStringToHex(fqdn)); /* ServerShortname (FQDN) */
                MailboxIDPointer.Append("00"); /* termination bit */
                MailboxIDPointer.Append(ConvertStringToHex(legacyDN)); /* Returns the userDN of the impersonated user */
                MailboxIDPointer.Append("00"); /* terminator bit */


                service.ImpersonatedUserId = null;
                return MailboxIDPointer.ToString();

            }

            static bool RedirectionUrlValidationCallback(String redirectionUrl)
            {
                bool redirectionValidated = false;
                if (redirectionUrl.Equals("https://SampleUrl/autodiscover/autodiscover.xml"))          
                {
                    redirectionValidated = true;
                }
                return redirectionValidated;
            }

            public String GetIntiatorEntryID(string domainName)
            {
                String result = String.Empty;

                //// Bind to EWS
                //ExchangeService service = ExchangeConnection.ExchangeService();
                //service.ImpersonatedUserId =
                //new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "user1@outlook.com");

                //// Get LegacyDN Using the function above this one 

                string sharedByLegacyDN = domainName;
                // A conversion function from earlier
                string legacyDNinHex = ConvertStringToHex(sharedByLegacyDN);



                StringBuilder addBookEntryId = new StringBuilder();



                addBookEntryId.Append("00000000"); /* Flags */
                addBookEntryId.Append("DCA740C8C042101AB4B908002B2FE182"); /* ProviderUID */
                addBookEntryId.Append("01000000"); /* Version */
                addBookEntryId.Append("00000000"); /* Type - 00 00 00 00  = Local Mail User */
                addBookEntryId.Append(legacyDNinHex); /* Returns the userDN of the impersonated user */
                addBookEntryId.Append("00"); /* terminator bit */


                result = addBookEntryId.ToString();
                //service.ImpersonatedUserId = null;
                return result;
            }

            public string ConvertStringToHex(string input)
            {
                // Take our input and break it into an array
                char[] arrInput = input.ToCharArray();
                String result = String.Empty;

                // For each set of characters
                foreach (char element in arrInput)
                {               
                    if (String.IsNullOrEmpty(result))
                    {
                        result = String.Format("{0:X2}", Convert.ToUInt16(element)).ToString();
                    }
                    else
                    {
                        result += String.Format("{0:X2}", Convert.ToUInt16(element)).ToString();
                    }

                }
                return result.ToString();
            }


     public string CreateSharingMessageAttachment(string folderid, string userSharing, string userSharingEntryID, string invitationMailboxID, string userSharedTo, string dataType, string calendarName)
            {
                XmlDocument sharedMetadataXML = new XmlDocument();
                string sharedMetaDataFilePath = string.Empty;
                try
                {

                    // Create a String that contains our new sharing_metadata.xml file
                    StringBuilder metadataString = new StringBuilder("<?xml version=\"1.0\"?>");              
                    metadataString.Append("<SharingMessage xmlns=\"http://schemas.microsoft.com/sharing/2008\">");
                    metadataString.Append("<DataType>" + dataType + "</DataType>");
                    metadataString.Append("<Initiator>");
                    metadataString.Append("<Name>" + userSharing + "</Name>");
                    metadataString.Append("<SmtpAddress>" + "Shyam@ProConstructor.com" + "</SmtpAddress><EntryId>" + userSharingEntryID.Trim());
                    metadataString.Append("</EntryId>");
                    metadataString.Append("</Initiator>");
                    metadataString.Append("<Invitation>");
                    metadataString.Append("<Title>" + calendarName + "</Title>");
                    metadataString.Append("<Providers>");
                    metadataString.Append("<Provider Type=\"ms-exchange-internal\" TargetRecipients=\"" + userSharedTo + "\">");
                    metadataString.Append("<FolderId xmlns=\"http://schemas.microsoft.com/exchange/sharing/2008\">");
                    metadataString.Append(folderid);
                    metadataString.Append("</FolderId>");
                    metadataString.Append("<MailboxId xmlns=\"http://schemas.microsoft.com/exchange/sharing/2008\">");
                    metadataString.Append(invitationMailboxID);
                    metadataString.Append("</MailboxId>");
                    metadataString.Append("</Provider>");
                    metadataString.Append("</Providers>");
                    metadataString.Append("</Invitation>");
                    metadataString.Append("</SharingMessage>");

                    sharedMetadataXML.LoadXml(metadataString.ToString());

                    string tempPath = System.IO.Path.GetTempPath();

                    sharedMetaDataFilePath = tempPath + "sharing_metadata.xml";
                    sharedMetadataXML.Save(sharedMetaDataFilePath);

                }
                catch (Exception eg)
                {
                    throw eg;               
                }
                return sharedMetaDataFilePath;
            }


            public Dictionary<string, string> GetUserSettings(AutodiscoverService autodiscoverService)
            {


                GetUserSettingsResponse userresponse = autodiscoverService.GetUserSettings(
                    "user1@outlook.com",
                    UserSettingName.UserDisplayName,
                    UserSettingName.InternalMailboxServerDN,
                    UserSettingName.UserDN
                );

                Dictionary<string, string> myUserSettings = new Dictionary<string, string>();

                foreach (KeyValuePair<UserSettingName, Object> usersetting in userresponse.Settings)
                {

                    if (usersetting.Key.ToString() == "InternalMailboxServerDN")
                    {
                        int lastIndexOfEqual = usersetting.Value.ToString().LastIndexOf("=");
                        string subString = usersetting.Value.ToString().Substring(lastIndexOfEqual + 1);

                        string value = subString;
                        myUserSettings.Add("InternalMailboxServer", value.ToString());

                    }
                    if (usersetting.Key.ToString() == "UserDisplayName")
                    {
                        string[] arrResult = usersetting.Value.ToString().Split('.');

                        myUserSettings.Add("UserDisplayName", arrResult[0].ToString());

                    }
                    if (usersetting.Key.ToString() == "UserDN")
                    {
                        string[] arrResult = usersetting.Value.ToString().Split('.');

                        myUserSettings.Add("UserDN", arrResult[0].ToString());

                    }
                }

                return myUserSettings;
            }

            private static byte[] HexStringToByteArray(string input)
            {

                byte[] Bytes;

                int ByteLength;

                string HexValue = "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9|||||||\xA\xB\xC\xD\xE\xF";

                ByteLength = input.Length / 2;

                Bytes = new byte[ByteLength];

                for (int x = 0, i = 0; i < input.Length; i += 2, x += 1)
                {
                    Bytes[x] = (byte)(HexValue[Char.ToUpper(input[i + 0]) - '0'] << 4);
                    Bytes[x] |= (byte)(HexValue[Char.ToUpper(input[i + 1]) - '0']);
                }

                return Bytes;
            }

    am i missing anything 

    any help is appreciated 

    Thanks in advance

    Wednesday, March 11, 2015 12:30 PM
  • Hi,

    I'm trying to share a calendar through ews managed api v.2 and using exchange 2013 version.

    i'm preparing a shared calendar and providing values to extended properties .

    Here comes the problem when i'm trying to send the sharing request(email message) 

    The following is code snippet.

                                                                                                                                                   

      public void ShareCalendar(Calendar calendar)
            {           
                ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
                  service.Credentials = new NetworkCredential("user1", "password", "domain");
                service.Url = new Uri("https://sampleUrl/ews/exchange.asmx");

                try
                {
                    // Bind to the folder
                    //Folder folderStoreInfo;
                    //folderStoreInfo = Folder.Bind(service, calendar.ExchangeId);
                    //string EwsID = folderStoreInfo.Id.UniqueId;
                    string EwsID = calendar.FolderExchangeId;

                    // The value of folderidHex will be what we need to use for the FolderId in the xml file

                    AutodiscoverService autoDiscover = new AutodiscoverService(ExchangeVersion.Exchange2013);
                    autoDiscover.Credentials =  new NetworkCredential("user1", "password", "domain");
                    autoDiscover.RedirectionUrlValidationCallback = RedirectionUrlValidationCallback;


                    Dictionary<string, string> userSettings = GetUserSettings(autoDiscover);

                    string folderidHex = GetConvertedEWSIDinHex(service, EwsID, "user1@outlook.com");

                    string domainName = string.Empty;
                    string mailBoxServer = string.Empty;
                    string userName = string.Empty;
                    foreach (var item in userSettings)
                    {
                        switch (item.Key)
                        {
                            case "UserDN":
                                domainName = item.Value.ToString();
                                break;
                            case "InternalMailboxServer":
                                mailBoxServer = item.Value.ToString();
                                break;
                            case "UserDisplayName":
                                userName = item.Value.ToString();
                                break;
                        }
                    }

                    string entryId = GetIntiatorEntryID(domainName);

                    string mailboxId = GetInvitationMailboxId(mailBoxServer, domainName);


                    string sharedFilePath = CreateSharingMessageAttachment(folderidHex, userName, entryId, mailboxId, "user2@outlook.com", "calendar", calendar.FolderName);



                    // Create a new message
                    EmailMessage invitationRequest = new EmailMessage(service);
                    invitationRequest.Subject = "I'd like to share my calendar with you";
                    invitationRequest.Body = "Sent by Exchange Administrator on behalf of user";                
                    //invitationRequest.Culture = "en-US";
                    invitationRequest.Sensitivity = Sensitivity.Normal;

                    // Set a sharing specific property on the message
                    invitationRequest.ItemClass = "IPM.Sharing"; /* Constant Required Value [MS-ProtocolSpec] */

                    byte[] byteEntryId = HexStringToByteArray(entryId);

                    // This is the Guid of the Sharing Provider in Exchange, and it's value does not change
                    Guid binSharingProviderGuid = new Guid("{AEF00600-0000-0000-C000-000000000046}");

                    // Even though I don't think setting this property is mandatory, 
                    // it just seemed like the right thing to do and it works so I \
                    // ain't messin with it!                                        
                    byte[] byteSharingProviderGuid = binSharingProviderGuid.ToByteArray();

                    string strPRBODYHTML = "<html dir=\"ltr\">\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\r\n<meta name=\"GENERATOR\" content=\"MSHTML 8.00.7601.17514\">\r\n<style id=\"owaParaStyle\">P {\r\n   MARGIN-TOP: 0px; MARGIN-BOTTOM: 0px \r\n}\r\n</style>\r\n</head>\r\n<body fPStyle=\"1\" ocsi=\"0\">\r\n<tt>\r\n<pre>SharedByUserDisplayName (SharedByUserSmtpAddress) has invited you to view his or her Microsoft Exchange Calendar.\r\n\r\nFor instructions on how to view shared folders on Exchange, see the following article:\r\n\r\nhttp://go.microsoft.com/fwlink/?LinkId=57561\r\n\r\n*~*~*~*~*~*~*~*~*~*\r\n\r\n</pre>\r\n</tt>\r\n<div>\r\n<div style=\"direction: ltr;font-family: Tahoma;color: #000000;font-size: 10pt;\">this is a test message</div>\r\n</div>\r\n</body>\r\n</html>\r\n";

                    string strBODY = @"
    SharedByUserDisplayName (SharedByUserSmtpAddress) has invited you to view his or
    her Microsoft Exchange Calendar.

    For instructions on how to view shared folders on Exchange, see the
    following article:

    http://go.microsoft.com/fwlink/?LinkId=57561

    *~*~*~*~*~*~*~*~*~*


    test body

    ";
                    // Convert these to hex and binary equivelants to assign to their relevant
                    // extended properties
                    string hexPRBODYHTML = ConvertStringToHex(strPRBODYHTML);
                    byte[] binPRBODYHTML = HexStringToByteArray(hexPRBODYHTML);

                    Guid PropertySetSharing = Guid.Parse("00062040-0000-0000-C000-000000000046");//constant 
                    Guid PropertySetInternetHeaders = Guid.Parse("00020386-0000-0000-C000-000000000046");//constant

                    ExtendedPropertyDefinition PidLidSharingProviderGuidProperty = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A01, MapiPropertyType.CLSID);
                    ExtendedPropertyDefinition ConversationIdProperty = new ExtendedPropertyDefinition(0x3013, MapiPropertyType.Binary);


                    // Sharing Properties (in order of reference according to protocol examples in: [MS-OXSHARE])

                    // Additional Property Constraints
                    // [MS-OXSHARE] 2.2.5.2
                    ExtendedPropertyDefinition PidTagMessageClass = new ExtendedPropertyDefinition(0x001A, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.5.1
                    //ExtendedPropertyDefinition PidNameContentClass = new ExtendedPropertyDefinition(DefaultExtendedPropertySet.InternetHeaders, "Content-Class", MapiPropertyType.String);
                    ExtendedPropertyDefinition PidNameContentClass = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "Content-class", MapiPropertyType.String);

                    // Common Message Object Properties               
                    // [MS-OXSHARE] 2.2.1
                    ExtendedPropertyDefinition PidTagNormalizedSubject = new ExtendedPropertyDefinition(0x0E1D, MapiPropertyType.String);
                    // The PidTagSubjectPrefix is a zero-length string, so I do not set it
                    // ExtendedPropertyDefinition PidTagSubjectPrefix = new ExtendedPropertyDefinition(0x003D, MapiPropertyType.String);

                    // Sharing Object Message Properties
                    // [MS-OXSHARE] 2.2.2.12
                    ExtendedPropertyDefinition PidLidSharingProviderGuid = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A01, MapiPropertyType.Binary);
                    // [MS-OXSHARE] 2.2.2.13
                    ExtendedPropertyDefinition PidNameXSharingProviderGuid = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Provider-GUID", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.14
                    ExtendedPropertyDefinition PidLidSharingProviderName = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A02, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.15           
                    ExtendedPropertyDefinition PidNameXSharingProviderName = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Provider-Name", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.16
                    ExtendedPropertyDefinition PidLidSharingProviderUrl = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A03, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.17
                    ExtendedPropertyDefinition PidNameXSharingProviderUrl = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Provider-URL", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.5
                    ExtendedPropertyDefinition PidLidSharingFlavor = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A18, MapiPropertyType.Integer);
                    // [MS-OXSHARE] 2.2.2.6
                    ExtendedPropertyDefinition PidNameXSharingFlavor = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Flavor", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.1
                    ExtendedPropertyDefinition PidLidSharingCapabilities = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A17, MapiPropertyType.Integer);
                    // [MS-OXSHARE] 2.2.2.2
                    ExtendedPropertyDefinition PidNameXSharingCapabilities = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Capabilities", MapiPropertyType.String);
                    // Sections 2.3 and 2.4 are also zero-length strings, so I won't set those either
                    // [MS-OXSHARE] 2.2.2.3
                    // ExtendedPropertyDefinition PidLidSharingConfigurationUrl = new   //ExtendedPropertyDefinition(PropertySetSharing, 0x8A24, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.4
                    //ExtendedPropertyDefinition PidNameXSharingConfigUrl = new //ExtendedPropertyDefinition(DefaultExtendedPropertySet.InternetHeaders, "X-Sharing-Config-Url", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.10
                    ExtendedPropertyDefinition PidLidSharingLocalType = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A14, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.11
                    ExtendedPropertyDefinition PidNameXSharingLocalType = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Local-Type", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.7
                    ExtendedPropertyDefinition PidLidSharingInitiatorEntryId = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A09, MapiPropertyType.Binary);
                    // [MS-OXSHARE] 2.2.2.8
                    ExtendedPropertyDefinition PidLidSharingInitiatorName = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A07, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.2.9
                    ExtendedPropertyDefinition PidLidSharingInitiatorSMTP = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A08, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.1
                    ExtendedPropertyDefinition PidLidSharingRemoteName = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A05, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.2 
                    ExtendedPropertyDefinition PidNameXSharingRemoteName = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Name", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.5 
                    ExtendedPropertyDefinition PidLidSharingRemoteType = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A1D, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.6 
                    ExtendedPropertyDefinition PidNameXSharingRemoteType = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Type", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.7 
                    ExtendedPropertyDefinition PidLidSharingRemoteUid = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A06, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.8 
                    ExtendedPropertyDefinition PidNameXSharingRemoteUid = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Uid", MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.3
                    ExtendedPropertyDefinition PidLidSharingRemoteStoreUid = new ExtendedPropertyDefinition(PropertySetSharing, 0x8A48, MapiPropertyType.String);
                    // [MS-OXSHARE] 2.2.3.4
                    ExtendedPropertyDefinition PidNameXSharingRemoteStoreUid = new ExtendedPropertyDefinition(PropertySetInternetHeaders, "X-Sharing-Remote-Store-Uid", MapiPropertyType.String);






                    //From troubleshooting I noticed I was missing
                    ExtendedPropertyDefinition PidTagPriority = new ExtendedPropertyDefinition(0x0026, MapiPropertyType.Integer);
                    ExtendedPropertyDefinition PidTagSensitivity = new ExtendedPropertyDefinition(0x0036, MapiPropertyType.Integer);
                    ExtendedPropertyDefinition PR_BODY_HTML = new ExtendedPropertyDefinition(0x1013, MapiPropertyType.Binary); //PR_BOD
                    ExtendedPropertyDefinition PR_BODY = new ExtendedPropertyDefinition(0x1000, MapiPropertyType.String);
                    ExtendedPropertyDefinition RecipientReassignmentProhibited = new ExtendedPropertyDefinition(0x002b, MapiPropertyType.Boolean);


                    // Section 2.2.1
                    invitationRequest.SetExtendedProperty(PidTagNormalizedSubject, "I'd like to share my calendar with you"); /* Constant Required Value [MS-OXSHARE] 2.2.1 */
                    //invitationRequest.SetExtendedProperty(PidTagSubjectPrefix, String.Empty); /* Constant Required Value [MS-OXSHARE] 2.2.1 */
                    // Section 2.2.2
                    invitationRequest.SetExtendedProperty(PidLidSharingCapabilities, 0x40220); /* value for Special Folders */
                    invitationRequest.SetExtendedProperty(PidNameXSharingCapabilities, "40220"); /* Test representation of SharingCapabilities value */
                    //invitationRequest.SetExtendedProperty(PidLidSharingConfigurationUrl, String.Empty); /* Zero-Length String [MS-OXSHARE] 2.2.2.3 */
                    //invitationRequest.SetExtendedProperty(PidNameXSharingConfigUrl, String.Empty); /* Zero-Length String [MS-OXSHARE] 2.2.2.4 */
                    invitationRequest.SetExtendedProperty(PidLidSharingFlavor, 0x20310); /* Indicates Invitation for a special folder [MS-OXSHARE] 2.2.2.5 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingFlavor, "20310"); /* Text representation of SharingFlavor value [MS-OXSHARE] 2.2.2.6 */
                    invitationRequest.SetExtendedProperty(PidLidSharingInitiatorEntryId, byteEntryId); /* Value from the Initiator/EntryId value in the Sharing Message attachment .xml document */
                    invitationRequest.SetExtendedProperty(PidLidSharingInitiatorSMTP, "user1@outlook.com"); /* Value from Initiator/Smtp Address in the Sharing message attachment .xml document */
                    invitationRequest.SetExtendedProperty(PidLidSharingInitiatorName, "User1"); /* Value from Initiator/Name Address in the Sharing message attachment .xml document */
                    invitationRequest.SetExtendedProperty(PidLidSharingLocalType, "IPF.Appointment"); /* MUST be set to PidTagContainerClass of folder to be shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingLocalType, "IPF.Appointment"); /* MUST be set to same value as PidLidSharingLocalType */
                    invitationRequest.SetExtendedProperty(PidLidSharingProviderGuid, byteSharingProviderGuid); /* Constant Required Value [MS-OXSHARE] 2.2.2.12 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingProviderGuid, "AEF0060000000000C000000000000046"); /* Constant Required Value [MS-OXSHARE] 2.2.2.13 */
                    invitationRequest.SetExtendedProperty(PidLidSharingProviderName, "Microsoft Exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.14 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingProviderName, "Microsoft Exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.15] */
                    invitationRequest.SetExtendedProperty(PidLidSharingProviderUrl, "http://www.microsoft.com/exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.16 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingProviderUrl, "http://www.microsoft.com/exchange"); /* Constant Required Value [MS-OXSHARE] 2.2.2.17 */
                    // Section 2.2.3
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteName, calendar.FolderName); /* MUST be set to PidTagDisplayName of the folder being shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteName, calendar.FolderName); /* MUST be set to same value as PidLidSharingRemoteName */
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteStoreUid, mailboxId); /* Must be set to PidTagStoreEntryId of the folder being shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteStoreUid, mailboxId); /* MUST be set to same value as PidLidSharingRemoteStoreUid */
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteType, "IPF.Appointment"); /* Constant Required Value [MS-OXSHARE] 2.2.3.5 */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteType, "IPF.Appointment"); /* Constant Required Value [MS-OXSHARE] 2.2.3.6 */
                    invitationRequest.SetExtendedProperty(PidLidSharingRemoteUid, folderidHex); /* MUST be set to PidTagEntryId of folder being shared */
                    invitationRequest.SetExtendedProperty(PidNameXSharingRemoteUid, folderidHex); /* Must be set to same value as PidLidSharingRemoteUid */
                    // Section 2.2.5
                    invitationRequest.SetExtendedProperty(PidNameContentClass, "Sharing"); /* Constant Required Value [MS-ProtocolSpec] */
                    invitationRequest.SetExtendedProperty(PidTagMessageClass, "IPM.Sharing"); /* Constant Required Value [MS-ProtocolSpec] */


                    // ********* ADDITIONAL MAPPED PROPERTIES IM FINDING AS I TROUBLESHOOT ********************** //
                    invitationRequest.SetExtendedProperty(PidTagPriority, 0); /* From troubleshooting I'm just trying to match up values that were missing */
                    invitationRequest.SetExtendedProperty(PidTagSensitivity, 0); /* From troubleshooting as well */
                    invitationRequest.SetExtendedProperty(PR_BODY_HTML, binPRBODYHTML); /* From troubleshooting OWA error pointing to serializing HTML failing */
                    invitationRequest.SetExtendedProperty(PR_BODY, strBODY);
                    invitationRequest.SetExtendedProperty(RecipientReassignmentProhibited, true); /* Because it seemed like a good idea */

                    // Add a file attachment by using a stream
                    // We need to do the following in order to prevent 3 extra bytes from being prepended to the attachment
                    string sharMetadata = File.ReadAllText(sharedFilePath, Encoding.ASCII);
                    byte[] fileContents;
                    UTF8Encoding encoding = new System.Text.UTF8Encoding();
                    fileContents = encoding.GetBytes(sharMetadata);
                    //fileContents = File.ReadAllBytes(sharedFilePath);

                    //// fileContents is a Stream object that represents the content of the file to attach.
                    invitationRequest.Attachments.AddFileAttachment("sharing_metadata.xml", fileContents);

                    ////invitationRequest.Attachments.AddFileAttachment(sharedFilePath);
                    //// This is where we set those "special" headers and other pertinent
                    //// information I noted in Part 1 of this series...
                    //Attachment thisAttachment = invitationRequest.Attachments[0];
                    //thisAttachment.ContentType = "application/x-sharing-metadata-xml";
                    //thisAttachment.Name = "sharing_metadata.xml";
                    //thisAttachment.IsInline = false;

                    // Add recipient info and send message
                    invitationRequest.ToRecipients.Add(new EmailAddress() { Address = "user2@outlook.com" });


                    invitationRequest.SendAndSaveCopy();

                    // I always end my methods by returning the EWS 
                    // impersonated user to null to clean up
                    service.ImpersonatedUserId = null;

                }
                catch (Exception ex)
                {

                }
            }

            public String GetConvertedEWSIDinHex(ExchangeService esb, String sID, String strSMTPAdd)
            {
                // Create a request to convert identifiers.
                AlternateId objAltID = new AlternateId();
                objAltID.Format = IdFormat.EwsId;
                objAltID.Mailbox = strSMTPAdd;
                objAltID.UniqueId = sID;

                //Convert  PR_ENTRYID identifier format to an EWS identifier.
                AlternateIdBase objAltIDBase = esb.ConvertId(objAltID, IdFormat.HexEntryId);
                AlternateId objAltIDResp = (AlternateId)objAltIDBase;
                return objAltIDResp.UniqueId.ToString();
            }

            public String GetInvitationMailboxId(string mailBoxServer, string domainName)
            {
                ExchangeService service = new ExchangeService(ExchangeVersion.Exchange2013);
                service.ImpersonatedUserId = new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "user1@outlook.com");
                // Generate The Store Entry Id for the impersonated user
                StringBuilder MailboxIDPointer = new StringBuilder();          
                string fqdn = mailBoxServer;
                string legacyDN = domainName;


                MailboxIDPointer.Append("00000000"); /* Flags */
                MailboxIDPointer.Append("38A1BB1005E5101AA1BB08002B2A56C2"); /* ProviderUID */
                MailboxIDPointer.Append("00"); /* Version */
                MailboxIDPointer.Append("00"); /* Flag */
                MailboxIDPointer.Append("454D534D44422E444C4C00000000"); /* DLLFileName */
                MailboxIDPointer.Append("00000000"); /* Wrapped Flags */
                MailboxIDPointer.Append("1B55FA20AA6611CD9BC800AA002FC45A"); /* WrappedProvider UID (Mailbox Store Object) */
                MailboxIDPointer.Append("0C000000"); /* Wrapped Type (Mailbox Store) */
                MailboxIDPointer.Append(ConvertStringToHex(fqdn)); /* ServerShortname (FQDN) */
                MailboxIDPointer.Append("00"); /* termination bit */
                MailboxIDPointer.Append(ConvertStringToHex(legacyDN)); /* Returns the userDN of the impersonated user */
                MailboxIDPointer.Append("00"); /* terminator bit */


                service.ImpersonatedUserId = null;
                return MailboxIDPointer.ToString();

            }

            static bool RedirectionUrlValidationCallback(String redirectionUrl)
            {
                bool redirectionValidated = false;
                if (redirectionUrl.Equals("https://SampleUrl/autodiscover/autodiscover.xml"))          
                {
                    redirectionValidated = true;
                }
                return redirectionValidated;
            }

            public String GetIntiatorEntryID(string domainName)
            {
                String result = String.Empty;

                //// Bind to EWS
                //ExchangeService service = ExchangeConnection.ExchangeService();
                //service.ImpersonatedUserId =
                //new ImpersonatedUserId(ConnectingIdType.SmtpAddress, "user1@outlook.com");

                //// Get LegacyDN Using the function above this one 

                string sharedByLegacyDN = domainName;
                // A conversion function from earlier
                string legacyDNinHex = ConvertStringToHex(sharedByLegacyDN);



                StringBuilder addBookEntryId = new StringBuilder();



                addBookEntryId.Append("00000000"); /* Flags */
                addBookEntryId.Append("DCA740C8C042101AB4B908002B2FE182"); /* ProviderUID */
                addBookEntryId.Append("01000000"); /* Version */
                addBookEntryId.Append("00000000"); /* Type - 00 00 00 00  = Local Mail User */
                addBookEntryId.Append(legacyDNinHex); /* Returns the userDN of the impersonated user */
                addBookEntryId.Append("00"); /* terminator bit */


                result = addBookEntryId.ToString();
                //service.ImpersonatedUserId = null;
                return result;
            }

            public string ConvertStringToHex(string input)
            {
                // Take our input and break it into an array
                char[] arrInput = input.ToCharArray();
                String result = String.Empty;

                // For each set of characters
                foreach (char element in arrInput)
                {               
                    if (String.IsNullOrEmpty(result))
                    {
                        result = String.Format("{0:X2}", Convert.ToUInt16(element)).ToString();
                    }
                    else
                    {
                        result += String.Format("{0:X2}", Convert.ToUInt16(element)).ToString();
                    }

                }
                return result.ToString();
            }


     public string CreateSharingMessageAttachment(string folderid, string userSharing, string userSharingEntryID, string invitationMailboxID, string userSharedTo, string dataType, string calendarName)
            {
                XmlDocument sharedMetadataXML = new XmlDocument();
                string sharedMetaDataFilePath = string.Empty;
                try
                {

                    // Create a String that contains our new sharing_metadata.xml file
                    StringBuilder metadataString = new StringBuilder("<?xml version=\"1.0\"?>");              
                    metadataString.Append("<SharingMessage xmlns=\"http://schemas.microsoft.com/sharing/2008\">");
                    metadataString.Append("<DataType>" + dataType + "</DataType>");
                    metadataString.Append("<Initiator>");
                    metadataString.Append("<Name>" + userSharing + "</Name>");
                    metadataString.Append("<SmtpAddress>" + "Shyam@ProConstructor.com" + "</SmtpAddress><EntryId>" + userSharingEntryID.Trim());
                    metadataString.Append("</EntryId>");
                    metadataString.Append("</Initiator>");
                    metadataString.Append("<Invitation>");
                    metadataString.Append("<Title>" + calendarName + "</Title>");
                    metadataString.Append("<Providers>");
                    metadataString.Append("<Provider Type=\"ms-exchange-internal\" TargetRecipients=\"" + userSharedTo + "\">");
                    metadataString.Append("<FolderId xmlns=\"http://schemas.microsoft.com/exchange/sharing/2008\">");
                    metadataString.Append(folderid);
                    metadataString.Append("</FolderId>");
                    metadataString.Append("<MailboxId xmlns=\"http://schemas.microsoft.com/exchange/sharing/2008\">");
                    metadataString.Append(invitationMailboxID);
                    metadataString.Append("</MailboxId>");
                    metadataString.Append("</Provider>");
                    metadataString.Append("</Providers>");
                    metadataString.Append("</Invitation>");
                    metadataString.Append("</SharingMessage>");

                    sharedMetadataXML.LoadXml(metadataString.ToString());

                    string tempPath = System.IO.Path.GetTempPath();

                    sharedMetaDataFilePath = tempPath + "sharing_metadata.xml";
                    sharedMetadataXML.Save(sharedMetaDataFilePath);

                }
                catch (Exception eg)
                {
                    throw eg;               
                }
                return sharedMetaDataFilePath;
            }


            public Dictionary<string, string> GetUserSettings(AutodiscoverService autodiscoverService)
            {


                GetUserSettingsResponse userresponse = autodiscoverService.GetUserSettings(
                    "user1@outlook.com",
                    UserSettingName.UserDisplayName,
                    UserSettingName.InternalMailboxServerDN,
                    UserSettingName.UserDN
                );

                Dictionary<string, string> myUserSettings = new Dictionary<string, string>();

                foreach (KeyValuePair<UserSettingName, Object> usersetting in userresponse.Settings)
                {

                    if (usersetting.Key.ToString() == "InternalMailboxServerDN")
                    {
                        int lastIndexOfEqual = usersetting.Value.ToString().LastIndexOf("=");
                        string subString = usersetting.Value.ToString().Substring(lastIndexOfEqual + 1);

                        string value = subString;
                        myUserSettings.Add("InternalMailboxServer", value.ToString());

                    }
                    if (usersetting.Key.ToString() == "UserDisplayName")
                    {
                        string[] arrResult = usersetting.Value.ToString().Split('.');

                        myUserSettings.Add("UserDisplayName", arrResult[0].ToString());

                    }
                    if (usersetting.Key.ToString() == "UserDN")
                    {
                        string[] arrResult = usersetting.Value.ToString().Split('.');

                        myUserSettings.Add("UserDN", arrResult[0].ToString());

                    }
                }

                return myUserSettings;
            }

            private static byte[] HexStringToByteArray(string input)
            {

                byte[] Bytes;

                int ByteLength;

                string HexValue = "\x0\x1\x2\x3\x4\x5\x6\x7\x8\x9|||||||\xA\xB\xC\xD\xE\xF";

                ByteLength = input.Length / 2;

                Bytes = new byte[ByteLength];

                for (int x = 0, i = 0; i < input.Length; i += 2, x += 1)
                {
                    Bytes[x] = (byte)(HexValue[Char.ToUpper(input[i + 0]) - '0'] << 4);
                    Bytes[x] |= (byte)(HexValue[Char.ToUpper(input[i + 1]) - '0']);
                }

                return Bytes;
            }

    am i missing anything 

    any help is appreciated 

    Thanks in advance

    Wednesday, March 11, 2015 12:33 PM
  • Hi Shyam0007,

    did you resolve the issue ,while i am facing it right now. thanks a lot for your reply. 

    Tuesday, November 20, 2018 10:03 AM