Welcome to MSDN Blogs Sign in | Join | Help

EWS has "More Happy" now - EWS Managed API and EWSEditor.

Want to make working with Exchange Web Services (EWS) much easier to work with?  There is a new API and new tool which can help.  No matter which way you are doing or going to be doing EWS calls, you should be familiar with both the Exchange Web Services Managed API and EWSEditor.

 

Exchange Web Services Managed API:

The Exchange Web Services Managed API makes life much easier since it wraps a lot of calling code and logic which is needed to successfully execute EWS calls.  No matter how you are doing EWS calls (pure soap calls, using generated .Net proxies or a third party API that does EWS calls), you should become familiar with this new API which released on Monday with Exchange 2010.  This API will work with both Exchange 2010 and 2007.  This API is a lot easier to use than other coding methods and can reduce code to well under 30% of what’s needed with generated proxy code (my observation).  Compared to WebDAV, you would need to write as little as 1.5% of the code with the EWS Managed API - an example of this is sending a meeting request. Yes, that 1.5% is correct.  As you can see, this new API is indeed the "go-forward" API for working with mailbox content.

 

EWSEditor:

There is a tool called EWSEditor which is written by a member of my team and used by our entire support team.  It’s based-upon the EWS Managed API and is helpful in showing how calls using this API can be used since you can get the source code.  We have been using it since Matt started building his tool using the early Beta of the Managed API in order help diagnose issues on customer’s systems.  Having source code samples when learning a new API is often invaluable, so be sure to get a copy of the source for EWSEditor to use as a reference.   Please check-out Matt’s blog below for more information on his tool and source code.

 

Announcing EWSEditor 1.5!

http://code.msdn.microsoft.com/ewseditor

 

ExchangeWebServices Namespace (generated .NET proxies)

http://msdn.microsoft.com/en-us/library/exchangewebservices.aspx

 

Exchange Web Services Managed API

http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=c3342fb3-fbcc-4127-becf-872c746840e1

 

Introducing the Exchange Web Services Managed API 1.0

http://msdn.microsoft.com/en-us/library/dd637749.aspx

 

Microsoft Exchange Web Services Managed API 1.0

http://msdn.microsoft.com/en-us/library/dd633709.aspx

 

One thing which I would strongly suggest is that if you find that your code does not work, try using EWSEditor to see if you can reproduce the issue.  If the operation you are trying to perform is not covered with EWSEditor, then try to see if the problem reproduces with the EWS Managed API.  EWSEditor & the EWS Managed API have the ability to log off EWS calls being performed.   You can use this logging feature to compare what EWSEditor/The EWS Managed API sends with what your application sends in order to determine where a problem is with your code.

 

Big kudos for…

The Exchange Development Team for creating the EWS Exchange Managed API.

Matt for building EWSEditor and getting it public!!!

 

 

               

My daughter wants "More Happy" also...

For Christmas my daughter is already asking for a netbook with Windows 7...  because she wants more "Happy".  If little Kylie can handle publishing and emailing under Windows 7, then my 10 year old should also be able to.   Her old clunker running XP needs to be retired, so I'm not totally against the idea of her getting an upgrade.  I think that I'll have to think about this one... and perhaps run it by Santa. 

Some of you may be wondering how well Windows 7 will run.  Hmmm, there are many ways to describe Windows 7... "Happy" would be a good description.  When our team was able to get the early Betas for Windows 7, we started switching over - overall performance and reliablity were big factors for the switch.  Some of us started loading Win 7 on netbooks since we wanted to see how well it ran - we were quite surprised with how well it ran... it actually ran really, really well.... so, well that it almost seemed to run as fast as Vista our multi-core boxes.  Myself, I just would have been "happy" to have far fewer pop-up boxes asking me if I really wanted to run stuff.  I've been using Windows 7 on several machines (desktops/laptops) for several months with a lot of different types of software and different hardware configurations and the experience has left me quite impressed.... In fact, I would say that more than "Happy" is comming... its lots of "Very Happy" which is comming.

So... I think my daughter should get more "Happy" also... 

HowTo: Create a mailbox for an existing user, Create a user in AD, List AD User info.

//======================================================================================================

// CdoexmMailboxUtil -

//    Exchange Mailbox and user account creation sample.

//

// This sample demonstrates the following:

//          Creating a user account in AD

//          Mail Enable an existing user.

//          List information on an existing user.

// Note: This code is provided as a sample only, so you need to test and take responsibility

//       of the code and any of its possible actions before usage. Being a sample, its provided

//       for educational purposes only and is not supported in any way.

// Note: Because CDOEX is used, you must run this on the Exchange server being accessed.

// Note: Because this code uses CDOEXM, it will not run on an Exchange 2007 server. For Exchange 2007,

//       you should use PowerShell instead.

// To compile:

//   Set references to CDOEXM and CDOEX:

//     CDOEX can be reference as this COM component: "Microsoft CDO for Exchange 2000 Library"

//          Note: Setting a reference to CDOEX will generate the "CDO" and "ADODB" interops.

//                If there is a preexisting ADODB interop, its usually best to remove it and let the

//                referencing of CDOEX generate the ADODB interop.

//     CDOEXM can be referenced as this COM component "CDO for Exchange Management"

//          Note: Setting a reference to will generate the CDOEXM iterop.

//     ActiveDS can be referenced as this COM component "Active DS Type Library"

//          Note: Setting a reference to will generate the ActiveDS iterop.

//

// Last changed 8/19/2009

// 

//======================================================================================================

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

using CDOEXM;

using CDO;

using ActiveDs;

using System.DirectoryServices;

using System.EnterpriseServices;

using System.Runtime.InteropServices;

 

namespace ExchangePfUtil

{

    class CdoexmMailboxUtil

    {

        //-------------------------------------------------------------------------------------------------------------------------------

        // TestCreateNewUserAndCreateMailbox – Create a new account, then independantly create the mailbox for it if the account was created.

        //-------------------------------------------------------------------------------------------------------------------------------

        public static bool TestCreateNewUserAndCreateMailbox()

        {

            bool bRet = false;

            string sFistName = "FirstName";

            string sLastName = "LastName";

            string sSamName = "firstlast";

            string sCreateUserBaseContainer = "LDAP://CN=Users,DC=171751dom,DC=net";

            string sCreateMailboxBaseContainer = "LDAP://DC=171751dom,DC=net";

            string sHomeMDB = "CN=Mailbox Store (AP1-109028),CN=First Storage Group,CN=InformationStore," +

                "CN=AP1-109028,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=First Organization," +

                "CN=Microsoft Exchange,CN=Services,CN=Configuration," +

                "DC=171751dom,DC=net";

            string sError = "";

            string UserId = null; // "Administrator";

            string Password = null; // "xxxx";

 

 

            bRet = CreateUser(sSamName, sFistName, sLastName, sCreateUserBaseContainer, sHomeMDB, out sError);

            if (bRet == true)

            {

                bRet = MailEnableUser(sHomeMDB, sSamName, sCreateMailboxBaseContainer, UserId, Password, out sError);

            }

 

            return bRet;

        }

 

        //-------------------------------------------------------------------------------------------------------------------------------

        // TestCreateMailBoxForExistingUser – test existing account created in Active Directory Users and Computers – with no mailbox.

        //-------------------------------------------------------------------------------------------------------------------------------

        public static bool TestCreateMailBoxForExistingUser()

        {

            bool bRet = false;

 

            string sSamName = "firstlastExisting";

           

            string sCreateMailboxBaseContainer = "LDAP://DC=171751dom,DC=net";

            string sHomeMDB = "CN=Mailbox Store (AP1-109028),CN=First Storage Group,CN=InformationStore," +

                "CN=AP1-109028,CN=Servers,CN=First Administrative Group,CN=Administrative Groups,CN=First Organization," +

                "CN=Microsoft Exchange,CN=Services,CN=Configuration," +

                "DC=171751dom,DC=net";

            string sError = "";

            string UserId = null; // "Administrator";

            string Password = null; // "xxxx";

 

 

 

            bRet = MailEnableUser(sHomeMDB, sSamName, sCreateMailboxBaseContainer, UserId, Password, out sError);

            

 

            return bRet;

        }

 

        //-----------------------------------------------------------------------------------------------------------------

        // CreateUser()

        //-----------------------------------------------------------------------------------------------------------------

        private static bool CreateUser(string sSamName, string sFistName, string sLastName, string sBaseContainer, string sHomeMDB, out string sErrorMessage)

        {

 

            bool bRet = false;

            string sError = "";

            try

            {

 

                DirectoryEntry oCont = new DirectoryEntry(sBaseContainer);

                IADsContainer oDSCont = null;

                IADsUser oUser = null;

 

                oDSCont = oCont.NativeObject as IADsContainer;

                oUser = oDSCont.Create("user", string.Format("CN={0} {1}", sFistName, sLastName)) as IADsUser;

                oUser.Put("sn", sLastName);

                oUser.Put("givenname", sFistName);

                oUser.Put("samaccountname", sSamName);

                oUser.SetInfo();

                oUser.AccountDisabled = false;

                oUser.SetInfo();

                bRet = true;

            }

            catch (Exception ex)

            {

                sError = ex.Message;

                Console.WriteLine("Failed to create user");

                Console.WriteLine(ex.Message);

                bRet = false;

            }

            sErrorMessage = sError;

            return bRet;

 

        }

 

        //--------------------------------------------------------------------------------------------

        // MailEnableUser

        //--------------------------------------------------------------------------------------------

        private static bool MailEnableUser(string sHomeMDB, string sSamName, string AdLdapPath, string AdUserId, string AdPassword, out string sErrorMessage)

        {

            string sError = "";

            bool bRet = false;

 

            DirectoryEntry oDirectoryEntryServer = new DirectoryEntry(AdLdapPath); //, null, null, AuthenticationTypes.Secure);

            try

            {

 

                DirectorySearcher oDirectorySearcher = new DirectorySearcher(oDirectoryEntryServer);

                oDirectorySearcher.Filter = "(SAMAccountName=" + sSamName + ")";

                SearchResult LDAPresult = oDirectorySearcher.FindOne();

                DirectoryEntry oDirectoryEntry = LDAPresult.GetDirectoryEntry();

 

                ActiveDs.IADsUser oUser = (IADsUser)oDirectoryEntry.NativeObject;

                //IMailboxStore oMailBox = null;

                bRet = CreateMailbox(oUser, sHomeMDB, out sError);

                bRet = true;

            }

            catch (Exception ex)

            {

                sError = ex.Message;

                Console.WriteLine("Could not get directory entry for user.");

                Console.WriteLine(ex.Message);

                bRet = false;

            }

            sErrorMessage = sError;

            return bRet;

        }

 

        //---------------------------------------------------------------------------------------------------

        // CreateMailbox

        //---------------------------------------------------------------------------------------------------

        private static bool CreateMailbox(IADsUser oUser, string sHomeMDB, out string sErrorMessage)

        {

            string sError = "";

            bool bRet = false;

            IMailboxStore oMailBox = null;

            try

            {

                oMailBox = (IMailboxStore)oUser;

                oMailBox.CreateMailbox(sHomeMDB);

                oUser.SetInfo();

                bRet = true;

            }

            catch (Exception ex)

            {

                sError = ex.Message;

                Console.WriteLine("Could not create mailbox.");

                Console.WriteLine(ex.Message);

                bRet = false;

            }

 

            Marshal.ReleaseComObject(oMailBox);

            sErrorMessage = sError;

            return bRet;

        }

 

        //---------------------------------------------------------------------------------------------------

        // UserInfo

        // Display info on a user account in AD.

        //---------------------------------------------------------------------------------------------------

        public static bool UserInfo(string sSamName, string AdLdapPath, string AdUserId, string AdPassword, out string sErrorMessage)

        {

            string sError = "";

            bool bRet = false;

 

            DirectoryEntry oDirectoryEntryServer = new DirectoryEntry(AdLdapPath); //, null, null, AuthenticationTypes.Secure);

            try

            {

 

                DirectorySearcher oDirectorySearcher = new DirectorySearcher(oDirectoryEntryServer);

                oDirectorySearcher.Filter = "(SAMAccountName=" + sSamName + ")";

                SearchResult LDAPresult = oDirectorySearcher.FindOne();

 

                DirectoryEntry oDirectoryEntry = LDAPresult.GetDirectoryEntry();

 

                ActiveDs.IADsUser oUser = (IADsUser)oDirectoryEntry.NativeObject;

                //IMailboxStore oMailBox = null;

                //Console.WriteLine(string.Format("distinguishedName: {0}", LDAPresult.Properties["distinguishedName"] ));

                Console.WriteLine(string.Format("FullName: {0}", oUser.FullName.ToString()));

                Console.WriteLine(string.Format("FirstName: {0}", oUser.FirstName.ToString()));

                Console.WriteLine(string.Format("LastName: {0}", oUser.LastName.ToString()));

                Console.WriteLine(string.Format("EmailAddress: {0}", oUser.EmailAddress.ToString()));

                Console.WriteLine(string.Format("ADsPath: {0}", oUser.ADsPath.ToString()));

                Console.WriteLine(string.Format("AccountDisabled: {0}", oUser.AccountDisabled.ToString()));

 

                bRet = true;

            }

            catch (Exception ex)

            {

                sError = ex.Message;

                Console.WriteLine("Error trying to find user.");

                Console.WriteLine(ex.Message);

                bRet = false;

            }

            sErrorMessage = sError;

            return bRet;

        }

 

 

    }

}

 

 

Here are some related links:

 

XADM: The CDOEXM IMailboxStore::CreateMailbox() or IMailboxStore::MoveMailbox() Method Fails

http://support.microsoft.com/kb/317234/

 

How to set Exchange Server 2000 and 2003 mailbox rights at the time of mailbox creation

http://support.microsoft.com/kb/304935

 

How to programmatically create a mailbox for an existing user in the Active Directory by using CDOEXM

http://support.microsoft.com/kb/327079

 

How to create a mailbox-enabled recipient by using Visual C#

http://support.microsoft.com/kb/313114

 

                HOWTO: Using CDOEXM in ASP.NET (.NET Framework 2.0 Walkthrough)

                http://blogs.msdn.com/mstehle/archive/2007/05/11/howto-using-cdoexm-in-asp-net-net-framework-2-0-walkthrough.aspx  

 

Howto: Mail Enable, Mail Disable and view Mail settings for a Public Folder with CDOEX and CDOEXM

If your living in a pre Exchange 2007 Powershell worlds and want to mail enable or disable public folders, you may come to the point where you will be needing to write some CDOEX and CDOEXM code to do what you want.  Below is a C# sample console application which will allow you to mail enable, mail disable and view mail settings on a public folder.

//======================================================================================================

// ExchangePfUtil -

//    Exchange Public Folder Sample.

//

// This sample demonstrates the following:

//          Check Mail setttings on a public folder

//          Mail Enable a public folder

//          Mail Disable setttings on a public folder

//          List sub-folders

//          List items in a folder

//          Delete an item or a folder

// Note: This code is provided as a sample only, so you need to test and take responsibility

//       of the code and any of its possible actions before usage. Being a sample, its provided

//       for educational purposes only and is not supported in any way.

// Note: Because CDOEX is used, you must run this on the Exchange server being accessed.

// Note: You should not need to supply a password.

// Note: Because this code uses CDOEXM, it will not run on an Exchange 2007 server. For Exchange 2007,

//       you should use PowerShell instead.

// To compile:

//   Set references to CDOEXM and CDOEX:

//     CDOEX can be reference as this COM component: "Microsoft CDO for Exchange 2000 Library"

//          Note: Setting a reference to CDOEX will generate the "CDO" and "ADODB" interops.

//                If there is a preexisting ADODB interop, its usually best to remove it and let the

//                referencing of CDOEX generate the ADODB interop.

//     CDOEXM can be referenced as this COM component "CDO for Exchange Management"

//          Note: Setting a reference to will generate the CDOEXM iterop.

//

// Last changed 8/17/2009

// 

//======================================================================================================

 

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using CDOEXM;

using CDO;

 

namespace ExchangePfUtil

{

    class Program

    {

        static void Main(string[] args)

        {

            string sURL = string.Empty;

            string sUserId = string.Empty;

            string sPassword = string.Empty;

            string sContentClass = string.Empty;

            string sOutlookFolderClass = string.Empty;

            bool bRet = false;

            string sErrorMessage = "";

            string sCommand = string.Empty;

 

            bool bOkToProcess = false;

 

 

            if (args.Length >= 2)

            {

                sCommand = args[0];

                sURL = args[1];

            }

           

 

 

            if (sURL.StartsWith("file://./backofficestorage/"))

                  bOkToProcess = true;

            else

                bOkToProcess = false;

 

            // Check Params

            if (bOkToProcess == true)

            {

                switch (sCommand)

                {

                    case "MailEnabledCheck":

                        if (args.Length == 2 || args.Length == 4)

                        {

                            if (args.Length == 4)

                            {

                                sUserId = args[2];

                                sPassword = args[3];

                            }

                            bOkToProcess = true;

                            bRet = MailEnabledCheck(sURL, sUserId, sPassword, out sErrorMessage);

                        }

                        else

                        {

                            bOkToProcess = false;

                            Console.WriteLine("Incorrect number of parameters.");

                        }

                        break;

                    case "MailDisable":

                        if (args.Length == 2 || args.Length == 4)

                        {

                            if (args.Length == 4)

                            {

                                sUserId = args[2];

                                sPassword = args[3];

                            }

                            bOkToProcess = true;

                            bRet = MailDisablePublicFolder(sURL, sUserId, sPassword, out sErrorMessage);

 

                        }

                        else

                        {

                            Console.WriteLine("Incorrect number of parameters.");

                            bOkToProcess = false;

                        }

                        break;

                    case "MailEnable":

                        if (args.Length == 2 || args.Length == 4)

                        {

                            if (args.Length == 4)

                            {

                                sUserId = args[2];

                                sPassword = args[3];

                            }

                            bOkToProcess = true;

                            bRet = MailEnabledPublicFolder(sURL, sUserId, sPassword, out sErrorMessage);

                        }

                        else

                        {

                            Console.WriteLine("Incorrect number of parameters.");

                            bOkToProcess = false;

                        }

                        break;

                    case "ListFolders":

                        if (args.Length == 2 || args.Length == 4)

                        {

                            if (args.Length == 4)

                            {

                                sUserId = args[2];

                                sPassword = args[3];

                            }

                            bOkToProcess = true;

                            bRet = ListFolders(sURL, sUserId, sPassword, out sErrorMessage);

                        }

                        else

                        {

                            Console.WriteLine("Incorrect number of parameters.");

                            bOkToProcess = false;

                        }

                        break;

                    case "CreateFolder":

 

                        if (args.Length == 2 || args.Length == 4 || args.Length == 6)

                        {

                            if (args.Length == 2)

                            {

                                // Default

                                sContentClass = "urn:content-classes:folder";

                                sOutlookFolderClass = "IPF.Note";

                            }

                            else

                            {

                                sContentClass = args[2];

                                sOutlookFolderClass = args[3];

                            }

                            if (args.Length == 6)

                            {

                                sUserId = args[4];

                                sPassword = args[5];

                            }

                            else

 

                            bOkToProcess = true;

                            bRet = CreateFolder(sURL, sUserId, sPassword, sContentClass, sOutlookFolderClass, out sErrorMessage);

                        }

                        else

                        {

                            Console.WriteLine("Incorrect number of parameters.");

                            bOkToProcess = false;

                            string sText = string.Empty;

                            sText = "Commonly used:\r\n";

                            sText += "  Type                 OutlookFolderClass   ContentClass\r\n";

                            sText += " +--------------------+--------------------+-----------------------------------r\n";

                            sText += "  Generic Folder       IPF.Note             urn:content-classes:folder \r\n";

                            sText += "  Mail Folder          IPF.Note             urn:content-classes:mailfolder \r\n";

                            sText += "  Contact Folder       IPF.Contact          urn:content-classes:contactfolder\r\n";

                            sText += "  Appointment Folder   IPF.Appointment      urn:content-classes:calendarfolder\r\n";

                            sText += "  Note Folder          IPF.Note             urn:content-classes:notesfolder\r\n";

                            sText += "  Task Folder          IPF.Task             urn:content-classes:taskfolder\r\n";

                            sText += "  Journal Folder       IPF.Journal          urn:content-classes:journalfolder\r\n";

                            Console.WriteLine(sText);

                        }

                        break;

                    case "ListItems":

                        if (args.Length == 2 || args.Length == 4)

                        {

                            if (args.Length == 4)

                            {

                                sUserId = args[2];

                                sPassword = args[3];

                            }

                            bOkToProcess = true;

                            bRet = ListItems(sURL, sUserId, sPassword, out sErrorMessage);

                        }

                        else

                        {

                            Console.WriteLine("Incorrect number of parameters.");

 

                            bOkToProcess = false;

                        }

                        break;

                    case "Delete":

                        if (args.Length == 2 || args.Length == 4)

                        {

                            if (args.Length == 4)

                            {

                                sUserId = args[2];

                                sPassword = args[3];

                            }

                            bOkToProcess = true;

                            bRet = DeleteFolderOrItem(sURL, sUserId, sPassword, out sErrorMessage);

                        }

                        else

                        {

                            Console.WriteLine("Incorrect number of parameters.");

 

                            bOkToProcess = false;

                        }

                        break;

                    default:

                        Console.WriteLine("Command Unknown: " + sCommand);

                        break;

                }

            }

 

 

            if (bOkToProcess == false)

            {

                // Error

                Console.WriteLine("Usage: ");

                Console.WriteLine("  ExchangePfUtil <Command> <FolderPath>");

                Console.WriteLine("  ExchangePfUtil <Command> <FolderPath> <Admin Account> <Password>");

                Console.WriteLine("  ExchangePfUtil <CreateFolder> <MessageClass>");

                Console.WriteLine("  ExchangePfUtil <CreateFolder> <MessageClass> <Admin Account> <Password>");

                Console.WriteLine("FolderPath needs to start with file://./backofficestorage/ ");

                Console.WriteLine("Commands:");

                Console.WriteLine("     MailEnabledCheck    - This will show Mail settings on the folder.");

                Console.WriteLine("     MailDisable         - This will show MailDisable the folder.");

                Console.WriteLine("     MailEnable          - This will show Mail Enable the folder");

                Console.WriteLine("     ListFolders         - This will list subfolders");

                Console.WriteLine("     CreateFolder        - This will create a folder");

                Console.WriteLine("     ListItems           - This will list items in a folder");

                Console.WriteLine("     Delete              - This will delete an item or folder");

 

                Console.WriteLine("Examples: ");

                Console.WriteLine("  ExchangePfUtil MailEnabledCheck \"file://./backofficestorage/myMailDom/public folders/myfolder\" ");

                Console.WriteLine("  ExchangePfUtil MailDisable \"file://./backofficestorage/myMailDom/public folders/myfolder\" Administrator AA12bc");

                Console.WriteLine("  ExchangePfUtil ListFolders \"file://./backofficestorage/myMailDom/public folders/myotherfolder\"  ");

                Console.WriteLine("  ExchangePfUtil CreateFolder \"file://./backofficestorage/myMailDom/public folders/myotherfolder\"  \"IPM.NOTE\" \"urn:content-classes:folder\"");

                bOkToProcess = false;

            

 

 

            }

        }

 

        static private bool MailDisablePublicFolder(string sURL, string sUserId, string sPassword, out string sErrorMessage)

        {

            bool bRet = false;

            string sError = "";

            CDO.Folder oPublicFolder = new CDO.Folder();

            CDOEXM.IMailRecipient oRecip;

 

 

            try

            {

                if (sUserId.Length != 0)

                {

                    oPublicFolder.DataSource.Open(

                                    sURL,

                                    null,

                                    ADODB.ConnectModeEnum.adModeReadWrite,

                                    ADODB.RecordCreateOptionsEnum.adFailIfNotExists,

                                    ADODB.RecordOpenOptionsEnum.adOpenExecuteCommand,

                                    sUserId,

                                    sPassword);

                }

                else

                {

                    oPublicFolder.DataSource.Open(

                        sURL,

                        null,

                        ADODB.ConnectModeEnum.adModeReadWrite,

                        ADODB.RecordCreateOptionsEnum.adFailIfNotExists,

                        ADODB.RecordOpenOptionsEnum.adOpenExecuteCommand,

                        string.Empty,

                        string.Empty);

                }

 

 

                oRecip = (CDOEXM.IMailRecipient)oPublicFolder;

 

 

                oRecip.MailDisable();

                oPublicFolder.DataSource.Save();

 

                Console.WriteLine("Mail Disabled Folder: " + sURL);

                Console.WriteLine("Note: It may take anywhere from a few seconds to minutes to take effect.");

                bRet = true;

 

                System.Runtime.InteropServices.Marshal.ReleaseComObject(oPublicFolder);

                System.Runtime.InteropServices.Marshal.ReleaseComObject(oRecip);

                

            }

            catch (Exception ex)

            {

                bRet = false;

                sError = ex.Message;

                Console.WriteLine("Failed to Mail Disable folder.");

                Console.WriteLine(sError);

            }

           

            sErrorMessage = sError;

            return bRet;

        }

 

        public static bool MailEnabledPublicFolder(string sURL, string sUserId, string sPassword,  out string sErrorMessage)

        {

            CDO.Folder oPublicFolder = new CDO.Folder();

            CDOEXM.IMailRecipient oRecip;

            ADODB.Connection oConn = new ADODB.Connection();

 

            string sError = "";

            bool bRet = false;

 

            try

            {

 

                oConn.Provider = "exoledb.datasource";

                if (sUserId.Length != 0)

                {

                    oConn.Open(sURL, sUserId, sPassword, 0);

                }

                else

                {

                    oConn.Open(sURL, string.Empty, string.Empty, 0);

                }

 

                oPublicFolder.DataSource.Open(sURL, oConn,

                        ADODB.ConnectModeEnum.adModeReadWrite,

                        ADODB.RecordCreateOptionsEnum.adFailIfNotExists,

                        ADODB.RecordOpenOptionsEnum.adOpenSource,

                        sUserId, sPassword);

 

 

                oRecip = (CDOEXM.IMailRecipient)oPublicFolder;

                oRecip.MailEnable(string.Empty);

                oPublicFolder.DataSource.Save();

                Console.WriteLine("Mail Enabled Folder: " + sURL);

                Console.WriteLine("Note: It may take anywhere from a few seconds to minutes to take effect.");

                bRet = true;

 

            }

            catch (Exception ex)

            {

                bRet = false;

                sError = ex.Message;

                Console.WriteLine("Failed to Mail Enable folder.");

                Console.WriteLine(sError);

            }

 

            oRecip = null;

            System.Runtime.InteropServices.Marshal.ReleaseComObject(oPublicFolder);

            System.Runtime.InteropServices.Marshal.ReleaseComObject(oConn);

 

            sErrorMessage = sError;

            return bRet;

        }

 

       private static bool MailEnabledCheck(string sURL, string sUserId, string sPassword, out string sErrorMessage)

        {

            CDO.Folder oPublicFolder = new CDO.Folder();

            CDOEXM.IMailRecipient oRecip ;

            ADODB.Connection oConn = new ADODB.Connection();

 

            string sError = "";

            bool bRet = false;

 

            try

            {

                oConn.Provider = "exoledb.datasource";

                if (sUserId.Length != 0)

                {

                    oConn.Open(sURL, sUserId, sPassword, 0);

                }

                else

                {

                    oConn.Open(sURL, string.Empty, string.Empty, 0);

                }

 

                oPublicFolder.DataSource.Open(sURL, oConn,

                        ADODB.ConnectModeEnum.adModeReadWrite,

                        ADODB.RecordCreateOptionsEnum.adFailIfNotExists,

                        ADODB.RecordOpenOptionsEnum.adOpenSource,

                        sUserId, sPassword);

 

 

                // Set MailEnabled property

                oRecip = (CDOEXM.IMailRecipient)oPublicFolder;

 

                Console.WriteLine ("Mail Settings:");

                Console.WriteLine("  PF: " + oPublicFolder.DisplayName);

                Console.WriteLine("  EmailAddress: " + oPublicFolder.EmailAddress);

                Console.WriteLine("  SMTPEmail: " + oRecip.SMTPEmail);

                Console.WriteLine("  TargetAddress: " + oRecip.TargetAddress);

                Console.WriteLine("  X400Email: " + oRecip.X400Email);

 

 

                bRet = true;

 

            }

            catch (Exception ex)

            {

                bRet = false;

                sError = ex.Message;

                Console.WriteLine("Could not check folder.");

                Console.WriteLine(sError);

            }

 

            // Explicitly release objects

            oRecip = null;

            System.Runtime.InteropServices.Marshal.ReleaseComObject(oPublicFolder);

            System.Runtime.InteropServices.Marshal.ReleaseComObject(oConn);

 

            sErrorMessage = sError;

            return bRet;

        }

       private static bool ListFolders(string sURL, string sUserId, string sPassword, out string sErrorMessage)

       {

            CDO.Folder oPublicFolder = new CDO.Folder();

           ADODB.Connection oConn = new ADODB.Connection();

 

            string sError = "";

            bool bRet = false;

 

            try

            {

                oConn.Provider = "exoledb.datasource";

                if (sUserId.Length != 0)

                {

                    oConn.Open(sURL, sUserId, sPassword, 0);

                }

                else

                {

                    oConn.Open(sURL, string.Empty, string.Empty, 0);

                }

 

                if (oConn.State == 1 )

                {

 

                    string sLine = string.Empty;

                   string sSQL = "";

                   sSQL = "SELECT " +

                            "\"DAV:href\", " +

                            "\"DAV:contentclass\", " +

                            "\"DAV:displayname\", " +

                            "\"DAV:hassubs\" " +

                            "FROM SCOPE ('SHALLOW TRAVERSAL OF \"" + sURL +

                            "\"') WHERE \"DAV:isfolder\" = true";

 

                    ADODB.Recordset oRecs = new ADODB.Recordset();

                    try

                    {

                        oRecs.CursorLocation = ADODB.CursorLocationEnum.adUseServer;

                        oRecs.Open (sSQL, oConn.ConnectionString,ADODB.CursorTypeEnum.adOpenUnspecified,

                                        ADODB.LockTypeEnum.adLockOptimistic, -1);

                        oRecs.MoveFirst();

                        if (oRecs.RecordCount > 0)

                        {

                            while(oRecs.EOF != true)

                            {

                                sLine = "";

                                //sLine = "[subfolders:" + oRecs.Fields["DAV:hassubs"].Value.ToString() + "] ";

                                //sLine = "[contentclass: " + oRecs.Fields["DAV:href"].Value.ToString() + "] ";

                                //sLine = "\"" + oRecs.Fields["DAV:displayname"].Value.ToString() + "\" ";

                                sLine += "" + oRecs.Fields["DAV:href"].Value.ToString() + "";

 

                                Console.WriteLine(sLine);

 

                                

 

                                oRecs.MoveNext();

                            }

                        }

                        else

                        {

 

                        }

 

                        bRet = true;

                    }

                    catch (Exception ex2)

                    {

                        sError = "Could not list folders.\r\n" + ex2.Message;

                        Console.WriteLine(sError);

                        bRet = false;

                    }

                    oRecs.Close();

                    System.Runtime.InteropServices.Marshal.ReleaseComObject(oRecs);

 

                }

                else

                {

 

                    sError = "Could not list folders.";

                    Console.WriteLine(sError);

                    bRet = false;

                }

 

            }

            catch (Exception ex)

            {

                bRet = false;

                sError = ex.Message;

         

                Console.WriteLine("Could not list folders:");

                Console.WriteLine(sError);

            }

 

            // Explicitly release objects

            System.Runtime.InteropServices.Marshal.ReleaseComObject(oPublicFolder);

            System.Runtime.InteropServices.Marshal.ReleaseComObject(oConn);

 

            sErrorMessage = sError;

            return bRet;

        }

 

       private static bool ListItems(string sURL, string sUserId, string sPassword, out string sErrorMessage)

       {

           CDO.Folder oPublicFolder = new CDO.Folder();

           ADODB.Connection oConn = new ADODB.Connection();

 

           string sError = "";

           bool bRet = false;

 

           try

           {

               oConn.Provider = "exoledb.datasource";

               if (sUserId.Length != 0)

               {

                   oConn.Open(sURL, sUserId, sPassword, 0);

               }

               else

               {

                   oConn.Open(sURL, string.Empty, string.Empty, 0);

               }

 

               if (oConn.State == 1)

               {

 

                   string sSQL = "";

                   sSQL = "SELECT " +

                            "\"DAV:href\", " +

                            "\"DAV:displayname\", " +

                            "\"DAV:ContentClass\" " +

                            "FROM SCOPE ('SHALLOW TRAVERSAL OF \"" + sURL +

                            "\"') WHERE \"DAV:isfolder\" = false";

 

                   ADODB.Recordset oRecs = new ADODB.Recordset();

                   try

                   {

                       string sLine = string.Empty;

                       oRecs.CursorLocation = ADODB.CursorLocationEnum.adUseServer;

                       oRecs.Open(sSQL, oConn.ConnectionString, ADODB.CursorTypeEnum.adOpenUnspecified,

                                       ADODB.LockTypeEnum.adLockOptimistic, -1);

                       oRecs.MoveFirst();

                       if (oRecs.RecordCount > 0)

                       {

                           while (oRecs.EOF != true)

                           {

                               sLine = "";

                               //sLine = "[contentclass: " + oRecs.Fields["DAV:href"].Value.ToString() + "] ";

                               //sLine = "\"" + oRecs.Fields["DAV:displayname"].Value.ToString() + "\" ";

                               sLine += "" + oRecs.Fields["DAV:href"].Value.ToString() + "";

 

                               Console.WriteLine(sLine);

                               oRecs.MoveNext();

                           }

                       }

 

                       bRet = true;

                       oRecs.Close();

                   }

                   catch (Exception ex2)

                   {

                       sError = "Could not list items - check path.\r\n" + ex2.Message;

                       Console.WriteLine(sError);

                       bRet = false;

                   }

                   

                   System.Runtime.InteropServices.Marshal.ReleaseComObject(oRecs);

 

               }

               else

               {

 

                   sError = "Could not list items.";

                   Console.WriteLine(sError);

                   bRet = false;

               }

 

           }

           catch (Exception ex)

           {

               bRet = false;

               sError = ex.Message;

 

               Console.WriteLine("Could not list items:");

               Console.WriteLine(sError);

           }

 

           // Explicitly release objects

           System.Runtime.InteropServices.Marshal.ReleaseComObject(oPublicFolder);

           System.Runtime.InteropServices.Marshal.ReleaseComObject(oConn);

 

           sErrorMessage = sError;

           return bRet;

       }

 

        private static bool CreateFolder(string sURL, string sUserId, string sPassword,

           string sContentClass,

           string sOutlookFolderClass,

           out string sErrorMessage)

        {

           CDO.Folder oPublicFolder = new CDO.Folder();

           ADODB.Connection oConn = new ADODB.Connection();

 

            string sError = "";

            bool bRet = false;

 

            try

            {

                oConn.Provider = "exoledb.datasource";

                if (sUserId.Length != 0)

                {

                    oConn.Open(sURL, sUserId, sPassword, 0);

                }

                else

                {

                    oConn.Open(sURL, string.Empty, string.Empty, 0);

                }

 

                if (oConn.State == 1 )

                {

                   oPublicFolder.ContentClass = sContentClass;

                   oPublicFolder.Fields["http://schemas.microsoft.com/exchange/outlookfolderclass"].Value = sOutlookFolderClass;

                   //oPublicFolder.Description = sDescription;

                   oPublicFolder.DataSource.SaveTo(sURL, oConn, ADODB.ConnectModeEnum.adModeReadWrite,

                       ADODB.RecordCreateOptionsEnum.adCreateCollection | ADODB.RecordCreateOptionsEnum.adCreateOverwrite,

                       ADODB.RecordOpenOptionsEnum.adOpenSource,

                       sUserId, sPassword);

                    bRet = true;

                }

                else

                {

 

                    sError = "Could not create folder.";

                    Console.WriteLine(sError);

                    bRet = false;

                }

 

            }

            catch (Exception ex)

            {

                bRet = false;

                sError = ex.Message;

                Console.WriteLine("Could not create folder.");

                Console.WriteLine(sError);

            }

 

            // Explicitly release objects

            System.Runtime.InteropServices.Marshal.ReleaseComObject(oPublicFolder);

            System.Runtime.InteropServices.Marshal.ReleaseComObject(oConn);

 

            sErrorMessage = sError;

            return bRet;

        }

 

        private static bool DeleteFolderOrItem(string sURL, string sUserId, string sPassword,out string sErrorMessage)

        {

            ADODB.Record oRec = new ADODB.Record();

            ADODB.Connection oConn = new ADODB.Connection();

 

            string sError = "";

            bool bRet = false;

 

            try

            {

                oConn.Provider = "exoledb.datasource";

                if (sUserId.Length != 0)

                {

                    oConn.Open(sURL, sUserId, sPassword, 0);

                }

                else

                {

                    oConn.Open(sURL, string.Empty, string.Empty, 0);

                }

 

                if (oConn.State == 1)

                {

                     try

                    {

                        oRec.Open(sURL, oConn, ADODB.ConnectModeEnum.adModeReadWrite,

                            ADODB.RecordCreateOptionsEnum.adFailIfNotExists,

                            ADODB.RecordOpenOptionsEnum.adOpenSource,

                            sUserId, sPassword);

 

                        try

                        {

                            //if (oRec.State == ADODB.ObjectStateEnum.adStateOpen)

                            oRec.DeleteRecord(sURL, false);

                            bRet = true;

                        }

                        catch (Exception ex3)

                        {

                            bRet = false;

                            sError = ex3.Message;

                            Console.WriteLine("Could not Delete - Call to delete the item failed.");

                            Console.WriteLine(sError);

                        }

                    }

                    catch (Exception ex2)

                    {

                        bRet = false;

                        sError = ex2.Message;

                        Console.WriteLine("Could not open item for deletion - check path.");

                        Console.WriteLine(sError);

                    }

 

                }

                else

                {

 

                    sError = "Could not Delete.";

                    Console.WriteLine(sError);

                    bRet = false;

                }

 

            }

            catch (Exception ex)

            {

                bRet = false;

                sError = ex.Message;

                Console.WriteLine("Could not Delete.");

                Console.WriteLine(sError);

            }

 

            // Explicitly release objects

            System.Runtime.InteropServices.Marshal.ReleaseComObject(oRec);

 

            System.Runtime.InteropServices.Marshal.ReleaseComObject(oConn);

 

            sErrorMessage = sError;

            return bRet;

        }  

 

    }

}

 

If you run into an issue with the code not mail enabling a folder, you should try to perform the same operation with Exchange System Manager (ESM).     If ESM cannot mail-enable or mail-disable a folder, then custom code will not likely either. When this happens, you should concentrate on getting ESM to enable/disable the folder first rather than trying to resolve the issue in custom code first.

 

If the public folder was migrated from Exchange 5.5 and will not mail enable or disable, then the pf_proxy_required may not be set.

 

You may receive a c1038a21 error message when you try to use Exchange System Manager to look at the properties of a public folder

http://support.microsoft.com/?id=328740

 

Microsoft Exchange Server Public Folder DAV-based Administration Tool

http://www.microsoft.com/downloads/details.aspx?FamilyId=635BE792-D8AD-49E3-ADA4-E2422C0AB424&displaylang=en  

 

PFDAVADMIN->connect to Server->Select Root public Folders->Click Tools->Custom

Bulk Operations

2- Type (DS:proxyaddresses=*) in the filter box

3- Click on ADD->Select other folder properties->ok

4- under the property box select PR_PF_PROXY_REQUIRED-> under value type 1 and

click on add-> click ok and again click ok

 

In Exchange 2007, you would use PowerShell to mail-enable a public folder:

 

How to Mail-Enable Public Folders: Exchange 2007 Help

http://technet.microsoft.com/en-us/library/aa997560.aspx

 

 

How to resolve the EWS ErrorNoPublicFolderServerAvailable error.

If you are using Exchange Web Services (EWS) against Exchange 2007 SP1, you may run into an issue where you are getting the ErrorNoPublicFolderServerAvailable and the error message says it’s not a proper error code.   This error appears if you have set the ”Exchange2007_SP1”, your code is accessing public folder and there is no public folder on the Exchange server. 

 

Here is an example of what you might get back when using auto-generated proxies:

 

Exception Type - System.InvalidOperationException
Exception Message - Instance validation error: 'ErrorNoPublicFolderServerAvailable' is not a valid value for ResponseCodeType.

 

See, public folders not installed by default when Exchange 2007 is installed.  Service Pack 1 for Exchange 2007 added support for public access with EWS if you add the ”Exchange2007_SP1” header to your EWS call.

 

“messages.xsd “is used for schema validation. So, it needs to be correct in order for validation to work.  As of  rollup 4, these are the only "PublicFolder"  errors enumerated in messages.xsd:

 

    <xs:enumeration value="ErrorNoPublicFolderReplicaAvailable"/>

    <xs:enumeration value="ErrorOperationNotAllowedWithPublicFolderRoot" />

    <xs:enumeration value="ErrorPublicFolderRequestProcessingFailed"/>

    <xs:enumeration value="ErrorPublicFolderServerNotFound"/>

 

So…   where is ErrorNoPublicFolderServerAvailable?

 

Apparently the “ErrorNoPublicFolderServerAvailable” enumeration error code was left out of messages.xsd and that’s what’s causing the xml parser to say it’s not a valid error code.  The solution for making it a valid error code is to put that error code into the XSD as a viable error code.

 

The suggested thing to do is add the ErrorNoPublicFolderServerAvailable entry to messages.xsd (usually located under "C:\Program Files\Microsoft\Exchange Server\ClientAccess\exchweb\ews") and regenerating the proxies to see if it resolves the issue with the error. The only change to message.xsd file is to add an enumeration to the schema which covers this error.  

      <xs:enumeration value=ErrorNoPublicFolderServerAvailable"/>

Here is what to try for the work-around:

 

1.     Copy the services.wsdl, messages.xsd, and types.xsd files down from your CAS server onto your local machine where you're running the Visual Studio proxy generator.

 

2. Edit the file "messages.xsd." and add the enumeration value ErrorNoPublicFolderServerAvailable to the ResponseCodeType enumeration in that file. This means you'll add a line that looks like:

 

<xs:enumeration value="ErrorNoPublicFolderServerAvailable" />

 

3. Generate new proxy classes using the WSDL/XSD files on your local machine (instead of from the Exchange server)

 

Read the following for more information on the ”Exchange2007_SP1” header:

 

Updating Exchange Server 2007 Exchange Web Service Clients to SP1

http://blogs.msdn.com/exchangedev/archive/2007/09/06/updating-exchange-server-2007-exchange-web-service-clients-to-sp1.aspx

How do I force OWA to only the web page in Engish?

There is no supported way to do this.  OWA uses the IE language settings to decide which language to display. Remember that OWA is a web application and goes off of browser settings just like most every other web site out there.  During the intial log-in to OWA you can set the language to use in OWA.  You can also override the language setting once logged-into OWA.  However, there is no supported way of forcing Englishe or any other language to be a speicific language other than to change IE (or other browser) language settings.

Below is an unsupported work-around for this issue.   Such code would be not supported or advised to use with OWA – so its a “use at your own risk” deal.  While there is support for writing ISAPI extensions and filters, there is no developer support for getting such a filter to work with OWA traffic.  ISAPI filters/extensions are notorious for messing-up OWA.  If such a filter were to be used and you need to call in for support, you may be asked to remove such a filter for troubleshooting.

    How to hard code the language of OWA interface
    http://support.microsoft.com/default.aspx?scid=kb;en-us;q310599

    IIS 6.0: ISAPI Filters for Earlier Versions of IIS May Not Load
    http://support.microsoft.com/default.aspx?scid=kb;en-us;327611

 


 

Don't redistribute product DLLs unless you know its safe and legal to do so.

Redistribution of files in the “C:\Program Files\Microsoft\Exchange Server” folder and sub-folders is not advised/supported.  Yes, this does include the “C:\Program Files\Microsoft\Exchange Server\Public” folder also.  These files are installed when the Exchange 2007 (or later) tools are installed.  If you need these files with the minimal installation, then use the Exchange installer to install them – the box will need to be at least in an Exchange Admin role.  There is no installer/redistributable which can be included with an application install – you have to run the installer for Exchange.

 

Files in product folder are not to be redistributed unless there is documentations saying that they may be.  Please refer to the EULA (End User License Agreement) which accompanies the installer for Exchange and note the text on redistribution.  Many DLLs and other files are part of a system of interdependent files and registry entries; distribution of any set of files incorrectly may likely fail at some point unless those files were designed for such distribution.   

 

When developing using APIs which are tied to a product, it’s very important that the files of that product are not distributed unless you know that it’s safe and legal to do so –in many cases it’s not.  Including product DLLs (in this case Microsoft’s) or OS DLLs (i.e. from Windows) should always be avoided.  In some cases severe (unrecoverable/data damaging) problems can occur from including such components with an application install. 

 

Here are some (not all) Exchange 2007 DLLs developers commonly ask if they can redistribute:

 

Microsoft.Exchange.Data.Common.dll

Microsoft.Exchange.Data.Directory.dll

Microsoft.Exchange.Data.dll

 

Here are some related links:

 

Find End User License Terms for Microsoft Software Licensed by Microsoft or the Computer Manufacturer

http://www.microsoft.com/about/legal/useterms/default.aspx

 

Microsoft .NET Namespaces for Exchange

http://msdn.microsoft.com/en-us/library/aa580926.aspx

 

Handling results of calling Power Shell – Multivalve and string arrays.

http://blogs.msdn.com/webdav_101/archive/2008/02/08/handling-results-of-calling-powershell-multivalued-and-string-arrays.aspx

 

How the Runtime Locates Assemblies

http://msdn.microsoft.com/en-us/library/yx7xezcf(VS.85).aspx

 

Howto: Set multiple extended properties on a folder using raw XML for EWS with a POST

Hmmm, there are very few samples on setting multiple extended properties on folders using a POST to EWS... so, I thought I would blog one.

 

This sample can be used with:

     http://blogs.msdn.com/webdav_101/archive/2009/02/27/howto-post-xml-to-ews-using-exchangeservicebinding-credentials.aspx 

 

Note the following:

                The version is set.

                Each property being set is done under a separate SetFolderField node.

 

<?xml version="1.0" encoding="utf-8"?>

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"

               xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">

  <soap:Header>

      <t:RequestServerVersion Version="Exchange2007_SP1" />

  </soap:Header>

  <soap:Body>

    <UpdateFolder xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"

                  xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">

      <FolderChanges>

        <t:FolderChange>

          <t:FolderId Id="AAMkAGYyN2JmMDM5LThiMGQtNDg2NC1iOTJiLTcwNTAzYzA4MTJmZgAuAAAAAADQwmwDLXTRQqgtmPQzUYndAQAD87SOmtYKQJJgvwQj7+EZAITQgdTRAAA="

                            ChangeKey="AQAAABYAAAAD87SOmtYKQJJgvwQj7+EZAITUPEsA"/>

          <t:Updates>

            <t:SetFolderField>

                <t:ExtendedFieldURI 

                                                DistinguishedPropertySetId="PublicStrings"

                        PropertyName="TestA"

                        PropertyType="String"/>

                       <t:Folder>

                 <t:ExtendedProperty>

                    <t:ExtendedFieldURI 

                                                DistinguishedPropertySetId="PublicStrings"

                        PropertyName="TestA"

                        PropertyType="String"/>

                    <t:Value>testa</t:Value>

                </t:ExtendedProperty>

                </t:Folder>

            </t:SetFolderField>

 

            <t:SetFolderField>

                <t:ExtendedFieldURI  

                                PropertySetId="A29B59B5-4B75-57B7-A24F-23D6CD6C556C"

                        PropertyName="FolderB"

                        PropertyType="String"/>

                       <t:Folder>

                 <t:ExtendedProperty>

                    <t:ExtendedFieldURI 

                                        PropertySetId="A29B59B5-4B75-57B7-A24F-23D6CD6C556C"

                        PropertyName="FolderB"

                        PropertyType="String"/>

                    <t:Value>TestColor</t:Value>

                </t:ExtendedProperty>

                </t:Folder>

            </t:SetFolderField>

 

            <t:SetFolderField>

                <t:ExtendedFieldURI 

                                PropertySetId="A29B59B5-4B75-57B7-A24F-23D6CD6C556C"

                        PropertyName="TestC"

                        PropertyType="Integer"/>

                       <t:Folder>

                 <t:ExtendedProperty>

                    <t:ExtendedFieldURI 

                                        PropertySetId="A29B59B5-4B75-57B7-A24F-23D6CD6C556C"

                        PropertyName="TestC"

                        PropertyType="Integer"/>

                    <t:Value>3</t:Value>

                </t:ExtendedProperty>

                </t:Folder>

            </t:SetFolderField>

 

          </t:Updates>

        </t:FolderChange>

      </FolderChanges>

    </UpdateFolder>

  </soap:Body>

</soap:Envelope>

 

Howto: Post XML to EWS using ExchangeServiceBinding credentials.

Here is a sample which shows how to use the connection of the Exchange Service Binding to do a POST to EWS using an XML string.   

 

 

// Sample calling code:

private void cmdExecute_Click(object sender, EventArgs e)

{

    string sRequest = string.Empty;

 

    bool bRet = false;

    

    string sResponse = string.Empty;

 

    bRet = EwsHelper.DoSoapRequest(

                sURL,

                oExchangeServiceBinding.Credentials,

                sRequestXml,

                ref sResponse

                );

 

    txtResponse.Text = sResponse;

}

 

// Sample of implementation:

 

using System;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Xml;

using System.Xml.Serialization;

using System.Net;

using System.Windows.Forms;

using MyExplorerApp.MyWebServiceRef;

 

// -------------------------------------------------------------------------------------------------------------

// DoSoapRequest

//  sEwsUrl - this is the url to the exchange.asmx

//  oCredentials - this is the credentials object from the ExchangeServiceBinding.

//  EWSRequestString - What you are requesting

//  EWSResponseString - The response string.

// -------------------------------------------------------------------------------------------------------------

public static bool DoSoapRequest(string sEwsUrl, ICredentials oCredentials, string EWSRequestString, ref string EWSResponseString)

{

    bool bError = false;

    EWSResponseString = "";

    HttpWebRequest webRequest = (HttpWebRequest)HttpWebRequest.Create(sEwsUrl);

 

    webRequest.Method = "POST";

    webRequest.ContentType = "text/xml;utf-8";

    

    webRequest.Credentials = oCredentials;

 

    byte[] requestBytes = System.Text.Encoding.UTF8.GetBytes(EWSRequestString);

 

    webRequest.ContentLength = requestBytes.Length;

    using (Stream requestStream = webRequest.GetRequestStream())  // Fill Request.

    {

        requestStream.Write(requestBytes, 0, requestBytes.Length);

        requestStream.Flush();

        requestStream.Close();

    }

    string sError = string.Empty;

    HttpWebResponse webResponse = null;

    try

    {

        webResponse = webRequest.GetResponse() as HttpWebResponse; // Get Response

    }

    catch (WebException webException)

    {

        HttpWebResponse httpResponse = webException.Response as HttpWebResponse;

        using (Stream responseStream = httpResponse.GetResponseStream())

        {

            StreamReader reader = new StreamReader(responseStream);

            sError = reader.ReadToEnd();

            MessageBox.Show(sError, "Error");

            bError = true;

        }

    }

 

    XmlDocument doc = new XmlDocument();

    // Read Response Stream

    if (bError == false)

    {

        string sResponse = string.Empty;

        using (Stream responseStream = webResponse.GetResponseStream())

        {

            StreamReader reader = new StreamReader(responseStream, Encoding.ASCII);

            sResponse = reader.ReadToEnd();

        }

 

        EWSResponseString = sResponse;

    }

 

    webRequest.Credentials = null;

 

    return bError;

}

Example: How to use PS_INTERNET_HEADERS with cdo 1.21 for custom properties.

'This example uses PS_INTERNET_HEADERS for setting a custom property

const smbx="mymailbox"  ' TODO: Change
const ssrv="myserver"      ' TODO: Change
const mycdoInetPset = "8603020000000000C000000000000046"
const myXheader = "X-SPAM"  ' TODO: Change to your property


set oses=createobject("mapi.session")
oses.logon "", "", false, true, 0, true, ssrv & vblf & smbx
set omsg=oses.inbox.messages.getfirst
sfrom=omsg.fields.item(myXheader,myCdoInetPset).value
wscript.echo sfrom
omsg.fields.add myXheader, vbString, "I Hate Spam!", myCdoInetPset
omsg.update

set omsg=nothing
set oses=nothing

Sample: How to get the number of file attachments with EWS.

Since HasAttachments does not really give you the number of file attachments, we you will find that you need to work around it.  You can use code like that below to get the real count of file attachments on an item.

 

    // -----------------------------------------------------------------------------------------

    // GetFileAttachmentsCount

    //   Returns number of attachments on an item.

    // -----------------------------------------------------------------------------------------

    public static int GetFileAttachmentsCount(ExchangeServiceBinding binding, ItemIdType id)

    {

        int iAttachmentCount = 0;

 

        // Use GetItem on the Id to get the Attachments collection 

        GetItemType getItemRequest = new GetItemType();

        getItemRequest.ItemIds = new ItemIdType[] { id };

        getItemRequest.ItemShape = new ItemResponseShapeType();

 

 

        getItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;

        PathToUnindexedFieldType hasAttachPath = new PathToUnindexedFieldType();

        hasAttachPath.FieldURI = UnindexedFieldURIType.itemHasAttachments;

        PathToUnindexedFieldType attachmentsPath = new PathToUnindexedFieldType();

        attachmentsPath.FieldURI = UnindexedFieldURIType.itemAttachments;

        // Add additional properties?

 

        getItemRequest.ItemShape.AdditionalProperties = new BasePathToElementType[]{

             hasAttachPath, attachmentsPath };

 

 

        GetItemResponseType getItemResponse = binding.GetItem(getItemRequest);

        ItemInfoResponseMessageType getItemResponseMessage = getItemResponse.ResponseMessages.Items[0] as ItemInfoResponseMessageType;

 

        if (getItemResponseMessage.ResponseCode == ResponseCodeType.NoError)

        {

            ItemType item = getItemResponseMessage.Items.Items[0];

            // Don't rely on  HasAttachments - It does not mean what you thing it would.

            if ((item.Attachments != null) && (item.Attachments.Length > 0))

            {

 

                for (int attachmentIndex = 0; attachmentIndex < item.Attachments.Length; attachmentIndex++)

                {

                    FileAttachmentType almostAnAttachment = item.Attachments[attachmentIndex] as FileAttachmentType;

                    if (almostAnAttachment != null)

                    {

                        iAttachmentCount += 1;

                    }

                }

 

            }

 

        }

        return iAttachmentCount;

    }

Sample: Howto display a list of calendar items in ListView using EWS

Here is a helpful sample of using EWS to get a list of calendar items and displaying them in a ListView. 

 

You should be able to use this with he sample I published prior on creating a CalendarView:

 

Sample: Using Calendar Views with EWS.

http://blogs.msdn.com/webdav_101/archive/2009/01/05/sample-using-calendar-views-with-ews.aspx

 

The sample below calls GetFileAttachmentsCount, which I have blogge here:

 

Sample: How to get the number of file attachments with EWS.

http://blogs.msdn.com/webdav_101/archive/2009/01/10/sample-how-to-get-the-number-of-file-attachments-with-ews.aspx

 

OK, on to the sample:

 

    //-------------------------------------------------------------------------------------------

    // RequestAndDisplayCalendarFullView

    // Populates the ListView with a list of appointments defined in the calendar view.

    //-------------------------------------------------------------------------------------------

    public static void RequestAndDisplayCalendarFullView(

                ExchangeServiceBinding binding,

                CalendarViewType calendarView,

                ref ListView lvView)

    {

 

 

        FindItemType findItemRequest = new FindItemType();

        findItemRequest.ParentFolderIds = new DistinguishedFolderIdType[] { new DistinguishedFolderIdType() };

        ((DistinguishedFolderIdType)findItemRequest.ParentFolderIds[0]).Id =

            DistinguishedFolderIdNameType.calendar;

 

        findItemRequest.Traversal = ItemQueryTraversalType.Shallow;

 

        ItemResponseShapeType itemShapeDefinition = new ItemResponseShapeType();

        itemShapeDefinition.BaseShape = DefaultShapeNamesType.AllProperties;

 

        findItemRequest.Item = calendarView;

        findItemRequest.ItemShape = itemShapeDefinition;

 

        // Do the EWS Call.

        FindItemResponseType findItemResponse = binding.FindItem(findItemRequest);

      

        if (findItemResponse.ResponseMessages.Items[0].ResponseClass !=

                ResponseClassType.Success)

        {

            // Indicate we have a problem

            throw new Exception(String.Format(

                "Unable to get calendar view\r\n{0}\r\n{1}",

                findItemResponse.ResponseMessages.Items[0].ResponseCode,

                findItemResponse.ResponseMessages.Items[0].MessageText));

        }

 

        FindItemResponseMessageType findItemResponseMessage =

            (FindItemResponseMessageType)findItemResponse.ResponseMessages.Items[0];

        ArrayOfRealItemsType findItemResponseItems =

            (ArrayOfRealItemsType)findItemResponseMessage.RootFolder.Item;

 

        ListViewItem lvItem = null;

        int iAttachmentCount = 0;

 

        lvView.Clear();

        lvView.View = View.Details;   // Set the view to show details.

        lvView.GridLines = true;      // Display grid lines.

        lvView.Columns.Add("Subject", 200, HorizontalAlignment.Left);

        lvView.Columns.Add("Recurring", 80, HorizontalAlignment.Left);

        lvView.Columns.Add("Start", 120, HorizontalAlignment.Left);

        lvView.Columns.Add("End", 120, HorizontalAlignment.Left);

        lvView.Columns.Add("Organizer", 80, HorizontalAlignment.Left);

        lvView.Columns.Add("#@", 40, HorizontalAlignment.Left);

        lvView.Columns.Add("Meeting", 80, HorizontalAlignment.Left);

 

        for (int x = 0;

            x < findItemResponseMessage.RootFolder.TotalItemsInView;

            x++)

        {

            CalendarItemType currentCalendarItem =

                (CalendarItemType)findItemResponseItems.Items[x];

 

            Debug.WriteLine(currentCalendarItem.Subject);

 

            lvItem = new ListViewItem(String.Format("{0}", currentCalendarItem.Subject, 0));

            lvItem.SubItems.Add(currentCalendarItem.IsRecurring.ToString());

            lvItem.SubItems.Add(currentCalendarItem.Start.ToLocalTime().ToString());

            lvItem.SubItems.Add(currentCalendarItem.End.ToLocalTime().ToString());

            lvItem.SubItems.Add(String.Format("{0}", currentCalendarItem.Organizer.Item.Name));

            iAttachmentCount = EwsAttachments.GetFileAttachmentsCount(binding, currentCalendarItem.ItemId);

            lvItem.SubItems.Add(String.Format("{0}", iAttachmentCount.ToString()));

            lvItem.SubItems.Add(String.Format("{0}", currentCalendarItem.IsMeeting.ToString()));

            lvItem.Tag = string.Format("{0}:{1}", currentCalendarItem.ItemId.Id, currentCalendarItem.ItemId.ChangeKey);

            lvView.Items.Add(lvItem);

 

            lvItem = null;

 

        }

    }

 

 

Ews; Exchange Web Services; list; appointments; appointment; calendaritem; DevMsgTeam; CalendarViewType; meeting;

Example: Populate a ListView with a list of attachments using EWS

I thought it would be fun to blog another sample of getting a list of attachments using EWS.  So, here is a handly method for populating a list of attachments.

 

    // -----------------------------------------------------------------------------------------

    // GetFileAttachmentsListLv

    //   Sets a listview to the attachments on an item.

    //   Returns number of attachments.

    // -----------------------------------------------------------------------------------------

    public static int GetFileAttachmentsListLv(ExchangeServiceBinding binding, ItemIdType id, ref ListView oListView)

    {

        int iAttachmentCount = 0;

        //List<RequestAttachmentIdType> attachmentIds = new List<RequestAttachmentIdType>();

 

        GetItemType getItemRequest = new GetItemType();

        getItemRequest.ItemIds = new ItemIdType[] { id };

        getItemRequest.ItemShape = new ItemResponseShapeType();

 

        getItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;

        PathToUnindexedFieldType hasAttachPath = new PathToUnindexedFieldType();

        hasAttachPath.FieldURI = UnindexedFieldURIType.itemHasAttachments;

        PathToUnindexedFieldType attachmentsPath = new PathToUnindexedFieldType();

        attachmentsPath.FieldURI = UnindexedFieldURIType.itemAttachments;

        // Add  additional properties...?

 

        getItemRequest.ItemShape.AdditionalProperties = new BasePathToElementType[]{

             hasAttachPath, attachmentsPath };

 

        GetItemResponseType getItemResponse = binding.GetItem(getItemRequest);

        ItemInfoResponseMessageType getItemResponseMessage = getItemResponse.ResponseMessages.Items[0] as ItemInfoResponseMessageType;

 

        oListView.Clear();

        oListView.View = View.Details;   // Set the view to show details.

        oListView.GridLines = true;      // Display grid lines.

        oListView.Columns.Add("Name", 90, HorizontalAlignment.Left);

        oListView.Columns.Add("Id", 120, HorizontalAlignment.Left);

        oListView.Columns.Add("RootItemId", 120, HorizontalAlignment.Left);

        oListView.Columns.Add("RootItemChangeKey", 120, HorizontalAlignment.Left);

        oListView.Columns.Add("ContentType", 80, HorizontalAlignment.Left);

        oListView.Columns.Add("ContentId", 80, HorizontalAlignment.Left);

        oListView.Columns.Add("ContentLocation", 80, HorizontalAlignment.Left);

 

        if (getItemResponseMessage.ResponseCode == ResponseCodeType.NoError)

        {

 

            ItemType item = getItemResponseMessage.Items.Items[0];

            // dont rely on item.HasAttachments - its mostly likely not set as you would think.

            if ((item.Attachments != null) && (item.Attachments.Length > 0))

            {

                for (int attachmentIndex = 0; attachmentIndex < item.Attachments.Length; attachmentIndex++)

                {

                    // For now, let's only consider file attachments instead of item attachments.

                    FileAttachmentType almostAnAttachment = item.Attachments[attachmentIndex] as FileAttachmentType;

                    if (almostAnAttachment != null)

                    {

                        // Note: Use GetAttachment to get the actual attachment.

 

                        RequestAttachmentIdType requestId = new RequestAttachmentIdType();

                        requestId.Id = almostAnAttachment.AttachmentId.Id;

 

                        ListViewItem lvItem = new ListViewItem(String.Format("{0}", almostAnAttachment.Name));

                        lvItem.SubItems.Add(String.Format("{0}", almostAnAttachment.AttachmentId.Id));

                        lvItem.SubItems.Add(String.Format("{0}", almostAnAttachment.AttachmentId.RootItemId));

                        lvItem.SubItems.Add(String.Format("{0}", almostAnAttachment.AttachmentId.RootItemChangeKey));

                        lvItem.SubItems.Add(String.Format("{0}", almostAnAttachment.ContentId));

                        lvItem.SubItems.Add(String.Format("{0}", almostAnAttachment.ContentLocation));

                        lvItem.SubItems.Add(String.Format("{0}", almostAnAttachment.ContentType));

                        oListView.Items.Add(lvItem);

 

                        lvItem = null;

 

                        iAttachmentCount++;

                    }

                }

 

            }

 

        }

 

        return iAttachmentCount;

    }

Sample: Using Calendar Views with EWS.

When working with Exchange Web Services (EWS) to do calendaring operations, you will likely run into the need to define calendar views.  A calendar view is a restriction/filer on the timespan of appointments and meetings you want to see in the calendar. To a beginner, how defining a calendar view properly can be a little bit confusing.  So, I put together some sample code I’ve used prior and am providing it here in case your looking for such samples.

 

 

Here is a sample of the calling code:

 

            CalendarViewType cvtView = GetCalendarViewForDay(2007,1, 6);

 

            txtDayView.Text = RequestAndDisplayCalendarView(_esb, cvtView);

 

Here is the implemented code:

 

        // -----------------------------------------------------------------

        // GetCalendarViewForToday

        // Returns a calendar view for today.

        // -----------------------------------------------------------------

        public static CalendarViewType GetCalendarViewForToday()

        {

            return GetCalendarViewForDay(

                    DateTime.Now.Year,

                    DateTime.Now.Month,

                    DateTime.Now.Day

                    );

        }

 

        // -----------------------------------------------------------------

        // GetCalendarViewForDay

        // Returns a calendar view for a given day.

        // -----------------------------------------------------------------

        public static CalendarViewType GetCalendarViewForDay(int iYear, int iMonth, int iDay)

        {

            DateTime dtToday12AM = new DateTime(iYear, iMonth, iDay, 0, 0, 0, DateTimeKind.Local);

            CalendarViewType calendarView = new CalendarViewType();

            calendarView.StartDate = dtToday12AM;

            calendarView.EndDate = calendarView.StartDate.AddDays(1);

            calendarView.MaxEntriesReturned = 99;

            calendarView.MaxEntriesReturnedSpecified = true;

            return calendarView;

        }

 

        // -----------------------------------------------------------------

        // GetCalendarViewForWeek

        // Returns a calendar view for the week of a given date.

        // -----------------------------------------------------------------

        public static CalendarViewType GetCalendarViewForWeek(int iYear, int iMonth, int iDay)

        {

            // create a date time instance which represents the day at 12:00:00am

            DateTime workDateTime = new DateTime(iYear, iMonth, iDay, 0, 0, 0, DateTimeKind.Local);

            DateTime FirstDOW = GetFirstDOW(workDateTime);

            DateTime LastDOW = GetLastDOW(workDateTime);

 

            CalendarViewType calendarView = new CalendarViewType();

            calendarView.StartDate = FirstDOW;

            calendarView.EndDate = LastDOW; 

            calendarView.MaxEntriesReturned = 99;

            // Don’t forget to set the specified flag

            calendarView.MaxEntriesReturnedSpecified = true;

            return calendarView;

        }

 

        // -----------------------------------------------------------------------

        // GetFirstDOW

        // Returns a the first day of the week for a given date.

        // In this routine, Sunday is considered to be the first day of the

        // However, the day considered to be the first day of the week may vary depending

        // upon culture. Cultural specific coding is not covered in this sample.

        // -----------------------------------------------------------------------

        public static DateTime GetFirstDOW(DateTime dtDate)

        {

            DateTime FirstDayofWeek = dtDate;

 

            //CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek

            switch (dtDate.DayOfWeek)

            {

                case DayOfWeek.Sunday:

                    FirstDayofWeek = dtDate;

                    break;

                case DayOfWeek.Monday:

                    FirstDayofWeek = dtDate.AddDays(-1);

                    break;

                case DayOfWeek.Tuesday:

                    FirstDayofWeek = dtDate.AddDays(-2);

                    break;

                case DayOfWeek.Wednesday:

                    FirstDayofWeek = dtDate.AddDays(-3);

                    break;

                case DayOfWeek.Thursday:

                    FirstDayofWeek = dtDate.AddDays(-4);

                    break;

                case DayOfWeek.Friday:

                    FirstDayofWeek = dtDate.AddDays(-5);

                    break;

                case DayOfWeek.Saturday:

                    FirstDayofWeek = dtDate.AddDays(-6);

                    break;

            }

            return FirstDayofWeek;

        }

 

        // -----------------------------------------------------------------------

        // GetLastDOW

        // Returns a the last day of the week for a given date.

        // In this routine, Sunday is considered to be the last day of the

        // However, the day considered to be the last day of the week may vary depending

        // upon culture. Cultural specific coding is not covered in this sample.

        // -----------------------------------------------------------------------

        public static DateTime GetLastDOW(DateTime dtDate)

        {

            DateTime LastDayofWeek = dtDate;

 

            //CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek

            switch (dtDate.DayOfWeek)

            {

                case DayOfWeek.Sunday:

                    LastDayofWeek = dtDate.AddDays(6);

                    break;

                case DayOfWeek.Monday:

                    LastDayofWeek = dtDate.AddDays(5);

                    break;

                case DayOfWeek.Tuesday:

                    LastDayofWeek = dtDate.AddDays(4);

                    break;

                case DayOfWeek.Wednesday:

                    LastDayofWeek = dtDate.AddDays(3);

                    break;

                case DayOfWeek.Thursday:

                    LastDayofWeek = dtDate.AddDays(2);

                    break;

                case DayOfWeek.Friday:

                    LastDayofWeek = dtDate.AddDays(1);

                    break;

                case DayOfWeek.Saturday:

                    LastDayofWeek = dtDate;

                    break;

            }

            return LastDayofWeek;

        }

 

        // -----------------------------------------------------------------------

        // GetCalendarViewForMonth

        // Returns a calendar view for a given year/month

        // -----------------------------------------------------------------------

        public static CalendarViewType GetCalendarViewForMonth(int iYear, int iMonth)

        {

            DateTime dtLastDayOfMonth = new DateTime(

                    iYear,

                    iMonth,

                    DateTime.DaysInMonth(iYear, iMonth)

                    );

 

            DateTime dtStart = new DateTime(

                    iYear, iMonth, 1,

                    0, 0, 0,

                    DateTimeKind.Local

                    );

 

            CalendarViewType calendarView = new CalendarViewType();

            calendarView.StartDate = dtStart;

            calendarView.EndDate = dtLastDayOfMonth;

            calendarView.MaxEntriesReturned = 100;

            calendarView.MaxEntriesReturnedSpecified = true;

            return calendarView;

        }

 

       //----------------------------------------------------------------------

        // GetCalendarItems

        // Returns a list of calendar items as text based on a calendar view.

        //----------------------------------------------------------------------

        public static string GetCalendarItems(

                    ExchangeServiceBinding binding,

                    CalendarViewType calendarView)

        {

            

            string sLine = "";

            string sLines = "";

 

            FindItemType findItemRequest = new FindItemType();

 

            findItemRequest.ParentFolderIds = new DistinguishedFolderIdType[] { new DistinguishedFolderIdType() };

            ((DistinguishedFolderIdType)findItemRequest.ParentFolderIds[0]).Id =

                DistinguishedFolderIdNameType.calendar;

 

            findItemRequest.Traversal = ItemQueryTraversalType.Shallow;

        

            ItemResponseShapeType itemShapeDefinition = new ItemResponseShapeType();

            itemShapeDefinition.BaseShape = DefaultShapeNamesType.AllProperties;

 

            findItemRequest.Item = calendarView;

            findItemRequest.ItemShape = itemShapeDefinition;

           

            // Do the EWS Call...

            FindItemResponseType findItemResponse = binding.FindItem(findItemRequest);

           

            // Check for errors?

            if (findItemResponse.ResponseMessages.Items[0].ResponseClass !=

            ResponseClassType.Success)

            {

 

                throw new Exception(String.Format( "Error:\r\n{0}\r\n{1}",

                    findItemResponse.ResponseMessages.Items[0].ResponseCode,

                    findItemResponse.ResponseMessages.Items[0].MessageText));

            }

            

    

            FindItemResponseMessageType findItemResponseMessage =

                (FindItemResponseMessageType)findItemResponse.

                    ResponseMessages.Items[0];

            ArrayOfRealItemsType findItemResponseItems =

                (ArrayOfRealItemsType)findItemResponseMessage.RootFolder.Item;

 

            sLine = string.Format(

                "There are {0} appointments between \r\n\t{1} on {2} and\r\n" +

                "\t{3} on {4}\r\n------------------------------\r\n",

                findItemResponseMessage.RootFolder.TotalItemsInView,

                calendarView.StartDate.ToLongTimeString(),

                calendarView.StartDate.ToLongDateString(),

                calendarView.EndDate.ToLongTimeString(),

                calendarView.EndDate.ToLongDateString());

            Debug.WriteLine(sLine);

            sLines = sLine;

 

            for (int x = 0;

                x < findItemResponseMessage.RootFolder.TotalItemsInView;

                x++)

            {

 

                CalendarItemType currentCalendarItem =

                    (CalendarItemType)findItemResponseItems.Items[x];

 

                Debug.WriteLine(currentCalendarItem.Subject);

               

                // Exchange stores all calendaring data in UTC time. So, convert to local

                // time so the person looking at the dates dont have to do the time math.

                sLine = "    Starts at: "+

                    currentCalendarItem.Start.ToLocalTime().ToShortTimeString()  +

                    " on " + currentCalendarItem.Start.ToLocalTime().DayOfWeek +

                    "  (" + currentCalendarItem.Start.ToString() + ")";

                Debug.WriteLine(sLine);

                sLines += sLine + "\r\n";

                sLine = "    Ends at: " +

                    currentCalendarItem.End.ToLocalTime().ToShortTimeString() +

                    " on " + currentCalendarItem.End.ToLocalTime().DayOfWeek +

                    "  (" + currentCalendarItem.End.ToString() + ")";

                Debug.WriteLine(sLine);

                sLines += sLine + "\r\n";

 

                Debug.WriteLine("    RecurrenceId: " + currentCalendarItem.RecurrenceId);

                Debug.WriteLine("    Id: " + currentCalendarItem.ItemId.Id);

                Debug.WriteLine("    ChangeKey: " + currentCalendarItem.ItemId.ChangeKey);

                Debug.WriteLine("    Organizer Name: " + currentCalendarItem.Organizer.Item.Name);

                Debug.WriteLine("    IsRecurring: " + currentCalendarItem.IsRecurring.ToString());

                Debug.WriteLine("    IsMeeting: " + currentCalendarItem.IsMeeting.ToString());

                Debug.WriteLine("    OriginalStart: " + currentCalendarItem.OriginalStart.ToString());

                Debug.WriteLine("    HasAttachments: " + currentCalendarItem.HasAttachments.ToString());

                Debug.WriteLine("    Attachments: ");

 

                sLines += "    RecurrenceId: " + currentCalendarItem.RecurrenceId+ "\r\n";

                sLines += "    Id: " + currentCalendarItem.ItemId.Id+ "\r\n";

                sLines += "    ChangeKey: " + currentCalendarItem.ItemId.ChangeKey+ "\r\n";

                sLines += "    Organizer Name: " + currentCalendarItem.Organizer.Item.Name+ "\r\n";

                sLines += "    IsRecurring: " + currentCalendarItem.IsRecurring.ToString()+ "\r\n";

                sLines += "    IsMeeting: " + currentCalendarItem.IsMeeting.ToString()+ "\r\n";

                sLines += "    OriginalStart: " + currentCalendarItem.OriginalStart.ToString()+ "\r\n";

                sLines += "    HasAttachments: " + currentCalendarItem.HasAttachments.ToString()+ "\r\n";

                sLines += "    Attachments: "+ "\r\n";

 

                // Note: You should not rely on the HasAttachments. 

                //  Please refer to: 

               //         Example: Returning a list of attachments using EWS

               //         http://blogs.msdn.com/webdav_101/archive/2009/01/05/example-returing-a-list-of-attachments-using-ews.aspx

 

                Debug.WriteLine("    xxxxxx  xxxxxx  xxxxxx  xxxxxx  xxxxxx");

                Debug.WriteLine("");

 

                sLines += "     \r\n  xxxxxx  xxxxxx  xxxxxx  xxxxxx  xxxxxx" + "\r\n";

                sLines += "" + "\r\n";

            }

 

            return sLines;

        }

Example: Returning a list of attachments using EWS

Here is a sample on getting and returning a list of attachments on an item using Exchange Web Services (EWS).

        //

        //-----------------------------------------------------------------------------------------

        // GetAttachmentsList.

        // Gets a list of file attachemnts on an item and puts them into <FileAttachmentType>.

        // Returns the number of attchments found.

        //

        // Here is how  you might call this code:

        //    List<FileAttachmentType> attachmentIds = null;

        //    string sLines = string.Empty;

        //    int iAttachments = 0;

        //    iAttachments = GetAttachmentsList(binding, currentCalendarItem.ItemId, ref attachmentIds);

        //    Debug.WriteLine(string.Format("{0} Attachments", iAttachments));

        //    foreach (FileAttachmentType oFileAttachmentType in attachmentIds)

        //    {

        //        sLines += "        Id:                " + oFileAttachmentType.AttachmentId.Id + "\r\n";

        //        sLines += "        RootItemId:        " + oFileAttachmentType.AttachmentId.RootItemId + "\r\n";

        //        sLines += "        RootItemChangeKey: " + oFileAttachmentType.AttachmentId.RootItemChangeKey + "\r\n";

        //        sLines += "        ContentId:         " + oFileAttachmentType.ContentId + "\r\n";

        //        sLines += "        ContentLocation:   " + oFileAttachmentType.ContentLocation + "\r\n";

        //        sLines += "        ContentType:       " + oFileAttachmentType.ContentType + "\r\n";

        //        sLines += "        Name:              " + oFileAttachmentType.Name + "\r\n";

        //        Debug.WriteLine(sLines);

        //    }

        //-----------------------------------------------------------------------------------------

        public static int GetAttachmentsList

            (

                ExchangeServiceBinding binding,

                ItemIdType id,

                ref List<FileAttachmentType> attachmentIds

            )

        {

 

            int iAttachmentCount = 0;

            attachmentIds = new List<FileAttachmentType>();

 

            GetItemType getItemRequest = new GetItemType();

            getItemRequest.ItemIds = new ItemIdType[] { id };

            getItemRequest.ItemShape = new ItemResponseShapeType();

 

            getItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;

            PathToUnindexedFieldType hasAttachPath = new PathToUnindexedFieldType();

            hasAttachPath.FieldURI = UnindexedFieldURIType.itemHasAttachments;

            PathToUnindexedFieldType attachmentsPath = new PathToUnindexedFieldType();

            attachmentsPath.FieldURI = UnindexedFieldURIType.itemAttachments;

 

            // Add  additional properties...? 

 

            //

            getItemRequest.ItemShape.AdditionalProperties = new BasePathToElementType[]{

                 hasAttachPath, attachmentsPath };

 

            GetItemResponseType getItemResponse = binding.GetItem(getItemRequest);

            ItemInfoResponseMessageType getItemResponseMessage = getItemResponse.ResponseMessages.Items[0] as ItemInfoResponseMessageType;

 

            if (getItemResponseMessage.ResponseCode == ResponseCodeType.NoError)

            {

 

                ItemType item = getItemResponseMessage.Items.Items[0];

                // Never rely on item.HasAttachments - its mostly likely not set as you would think.

                if ((item.Attachments != null) && (item.Attachments.Length > 0))

                    {

 

                    for (int attachmentIndex = 0; attachmentIndex < item.Attachments.Length; attachmentIndex++)

                    {

                        // For now, let's only consider file attachments instead of item attachments.

                        //

                        FileAttachmentType oFoundAttachment = item.Attachments[attachmentIndex] as FileAttachmentType;

                        if (oFoundAttachment != null)

                        {

                            attachmentIds.Add(oFoundAttachment);

                            //Debug.WriteLine(" Id: " + oFoundAttachment.AttachmentId.Id);

                            iAttachmentCount++;

                        }

                    }

                }

            }

 

            return iAttachmentCount;

        }

More Posts Next page »
 
Page view tracker