Quantcast
Channel: Outlook dev blog
Viewing all 108 articles
Browse latest View live

Exchange Web Services Update Rollup 4 Roundup

$
0
0

We have just released update rollup 4 (RU4) for Exchange 2007 SP1.  This rollup fixes some bugs in Exchange Web Services (EWS), and introduces some behavior changes to EWS to allow customers and partners the flexibility to accomplish some key scenarios.  If you have written code against Exchange Web Services, we definitely recommend that you take a look at RU4. The following are the biggest changes that will be coming in the rollup:

-          Item IDs are now returned after MoveItem/CopyItem calls.

-          Unknown/unsupported item types are returned as Messages.

-          Updating tasks can now have correct behavior for Start and Complete Date values.

ItemId of Item Is Returned After a MoveItem/CopyItem Call

Some of our observant developers have noticed that Exchange creates new destination item IDs for items when they are moved between folders. We created a place in the schema to return the destination ID of an item, and in the early stages of Exchange development, this ID was returned. We pulled it out late in the Exchange 2007 development cycle after we determined that the method of determining the destination ID was too resource-intensive. After consistent feedback from customers that this feature was needed so that items could be tracked as they were moved between folders, we implemented a much more performant solution.  Now, if you call MoveItem/CopyItem, you’ll be able to identify the new item in the destination folder by looking at the destination ID that is returned by the MoveItem/CopyItem call.

Note: Cross-mailbox or mailbox-to-public folder CopyItem/MoveItem calls will not return destination IDs and RU4 must be applied to both the Client Access Server and the Mailbox Server Role for this feature to work.

Non-IPM.Note.* Items Are Returned as Messages

EWS in Exchange 2007 SP1 uses the <Item> type as the base class for items that are not strongly typed.  This design has caused problems for customers who want to reply to item types that have a custom item class, or item types that EWS does not yet support, like IPM.Sharing or IPM.InfoPath. In RU4, all item types that we do not support natively in Exchange Web Services, like Journal, Sharing Requests, InfoPath forms, are returned as <Message> instead of <Item>.  This means that you can see all the recipient information on the item, mark it as unread, reply to it, or forward it just like you would a normal item (assuming that the object supports forwarding/replying). 

 

<Item> type still exists as a base class for <Message>, so most applications built on the auto-generated proxy classes will not be affected; however, applications that parse the XML directly could break if they are expecting <Item> rather than <Message>. To minimize the risk of breaking applications, this behavior is only applied when the Exchange2007_SP1 version header is specified. 

 

We don’t take making changes in a rollup that could break applications lightly; our goal is to only change protocol behavior with the introduction of a new version header. However, we felt that this functionality is critical for some of our partners and customers, has a minimal impact on the majority of applications, is the way EWS should have worked in the first place, and can’t wait for the next service pack for Exchange, which could introduce a schema change for a new version header. For more details about this topic, see Robin’s June post that describes the proposed change and asks for feedback.

 

 

Updating Recurring Tasks Now Works Correctly

In Exchange 2007 and Exchange 2007 SP1, when a task is updated, such as by marking CompleteDate, the Client Access server shifts the date specified as the complete date according to the offset of its time zone. This is bad because clients are rarely aware of the time zone that the server is operating in. If the Client Access server and the client time zones are far enough apart, tasks could be marked as completed on the wrong day — not good!

 

The problem is that no time zone information is passed to EWS in tasks, yet a time zone is required when saving/updating/getting tasks to make sure that the task is marked as completed on the correct day. To fix this problem, with RU4, EWS can treat offset date times in a special way when they are the Complete Date, Due Date, or Start Date elements of a task. The offset, for example 10:00:00T-08:00, is used to create a time zone for that offset. This time zone is used when the task is saved so that the date the task was completed is always the date intended.

 

This post only covers the changes in RU4 that we think are most interesting to Exchange Web Services developers. We will be posting this and additional information in KB articles shortly. We hope you find this information useful and as always appreciate your feedback.

Jason Henderson  and Andrew Salamatov

Learn about the Exchange Web Services Managed API and how Exchange is getting “Cloud Ready” at PDC’08

$
0
0

Those of you who have already made plans to catch PDC ’08 in L.A. at the end of October be sure to catch the Exchange Web Services Managed API: Unified Communications Development for Exchange session.  This exciting talk will be the coming out party for the managed API; it will be the first time that the API has been shown in public.  We’ll have live coding, demo’s, and of course answer your questions on everything Exchange development.  I’m looking forward to seeing you in L.A.!

 

Jason Henderson

MAPI documentation moved to Office

$
0
0

Just a quick note to all you fans of MAPI out there. Based on some discussions we had a while ago, the folks in Office have been putting a LOT of time and effort into improving the MAPI material, and bringing it up-to-date for Office 2007. Well, they’ve finished their work, and the improvements are substantial! Check out the new content on MSDN Library at: http://msdn.microsoft.com/en-us/library/cc765775.aspx. We plan to have a redirection page under Exchange Server for about six months, to remind you where the stuff went.

Thom Randolph (thomr@microsoft.com)

The December SDK is Here!

$
0
0

I am happy to announce that the December 2008 release of the Exchange Server 2007 SP1 SDK is available. And now, a Haiku for you.

Released new content.
Updated topics for you.
Go get the goods here.

Exchange Web Services Push Notifications Simplified

$
0
0

Using Exchange Web Services push notifications just got a lot easier, thanks to Exchange Server MVP Henning Krause. Henning has created a notification listener project on CodePlex. The listener application handles Exchange Web Services push notifications. The listener uses the WCF service model, and does not rely on IIS. Check it out, provide some feedback, and incorporate EWS push notifications into your Exchange Server client application.

Quick and Dirty UNIX Shell Scripting with EWS

$
0
0

One of the great advantages of Exchange Web Services (EWS) is that you can write applications on just about any platform that can make HTTP requests.  This characteristic of web services means that you can integrate EWS in to just about every application or environment you can imagine.  This aspect of web services was brought home to me the other day while using my Mac OS X laptop, which I have to test Microsoft Entourage Exchange Web Services Edition Beta against Exchange.  I wanted to quickly find the phone number for a colleague.  I knew I could find the information in Entourage, but I wanted to be able to get the information without leaving my terminal window, so I dug deep in my memory to my first programming project as a 10 year old on a Unix workstation writing shell scripts (yes, that is how my parents kept me occupied).

First, I needed a suitable utility to make an HTTP request, and preferably one that could perform Windows Integrated authentication, which is the default for EWS.  Curl is a great little tool for quickly issuing requests; it is supported cross-platform and has an NTLM authentication stack built in.  This cool post shows how to use it for building a Mac OSX Widget that works against EWS.  I extracted the necessary line and modified them for our use:

curl -s -u username@contoso.com:password -L https://servername/ews/exchange.asmx -d "$DATA" -H "Content-Type:text/xml"    --ntlm

 

Here is a breakdown of the parameters and their function:

–s parameter tells curl to run silently

 -u allows me to pass UPN and password on the command line

-L allows us to specify the URL

-d allows me to specify the body of the request should come from a variable called $DATA

 -H allows me to set the content header which is required

 –ntlm allows me to specify that Curl should try ntlm auth (--anyauth doesn’t work)

The request is then customized for the alias I want by piping the XML for the resolve names request through sed so that I can replace the alias to resolve with the alias I want to resolve as an argument to the utility that I’m going to call resolvename.

DATA=$(sed 's/alias/'$1'/' resolvenames.txt)

 

resolvenames.txt

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

<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

               xmlns:xsd="http://www.w3.org/2001/XMLSchema"

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

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

  <soap:Body>

    <ResolveNames xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"               xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types"

                  ReturnFullContactData="true">

      <UnresolvedEntry>alias</UnresolvedEntry>

    </ResolveNames>

  </soap:Body>

</soap:Envelope>

 

Getting this far is pretty easy and you are left with a simple utility which takes in an alias as a parameter, formats the request with the alias, and makes the request.  You can now take this output and pipe it to some utility which can consume it, ideally one that can natively handle the output xml. 

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

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

  <s:Header>

    <h:ServerVersionInfo MajorVersion="8" MinorVersion="1" MajorBuildNumber="200" MinorBuildNumber="1" xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types" xmlns="http://schemas.microsoft.com/exchange/services/2006/types" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"/></s:Header><s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">

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

        <m:ResponseMessages>

          <m:ResolveNamesResponseMessage ResponseClass="Success">

            <m:ResponseCode>NoError</m:ResponseCode>

            <m:ResolutionSet TotalItemsInView="1" IncludesLastItemInRange="true"><t:Resolution>

              <t:Mailbox>

                <t:Name>Jason Henderson</t:Name>

                <t:EmailAddress>jason@contoso.com</t:EmailAddress>

                <t:RoutingType>SMTP</t:RoutingType>

                <t:MailboxType>Mailbox</t:MailboxType>

              </t:Mailbox>

              <t:Contact>

                <t:Culture>en-US</t:Culture>

                <t:DisplayName>Jason Henderson</t:DisplayName>

                <t:GivenName>Jason</t:GivenName

                ><t:CompanyName>Contoso</t:CompanyName>

                <t:EmailAddresses>

                  <t:Entry Key="EmailAddress1">smtp:jason@contoso.com</t:Entry>

                    </t:EmailAddresses>

                <t:PhoneNumbers>

                  <t:Entry Key="BusinessPhone">555-5555</t:Entry></t:PhoneNumbers>

                <t:ContactSource>ActiveDirectory</t:ContactSource>

                <t:Department>Web Services</t:Department>

                <t:JobTitle>SENIOR PROGRAM MANAGER LEAD</t:JobTitle>

                <t:Manager>Bob Manager</t:Manager>

                <t:OfficeLocation>55/5555</t:OfficeLocation>

                <t:Surname>Henderson</t:Surname>

              </t:Contact></t:Resolution>

            </m:ResolutionSet>

          </m:ResolveNamesResponseMessage>

        </m:ResponseMessages>

      </m:ResolveNamesResponse>

    </s:Body>

</s:Envelope>

 

Since I did shell scripting before XML parsing was in high demand I don’t have any good XML parsing tools up my sleeve, just good old awk and sed.   After a couple of false starts I dropped a mail to my good friend John Muster, author of Unix Made Easy (always at my side when I do any kind of shell scripting) and asked for his help.  He quickly obliged with a quick and dirty XML parser using expr that we both admit is ugly and incomplete, but works well enough for parsing out office location, phone numbers, job titles, and any other standard field.  The complete listing of the utility I call resolvename is below.

resolvename

DATA=$(sed 's/alias/'$1'/' resolvenames.txt)

curl -s -u jasonhen@contoso.com:password -L https://servername/ews/exchange.asmx -d "$DATA"  -H "Content-Type:text/xml" --ntlm | tr -d '<:>' \

| tr ' ' '+' >  /tmp/output$$

expr `cat /tmp/output$$` :  '.*'$2'\(.*\)/\t'$2 > /tmp/selection$$

tr + ' '  < /tmp/selection$$

rm /tmp/output$$ /tmp/selection$$

 

The usage for the utility is: resolvename <alias> <xmlnode>, so for example “resolvename jason JobTitle” returns  “Senior Program Manager Lead” or “resolvename jasonhen OfficeLocation” returns my building and office number.  Pretty slick if I do say so myself.

Warnings – This code is not even prototype quality.  Among numerous other shortcomings, no error codes are handled, and XML parsing only works properly with elements that occur once and have no attributes.  If I were going to write a production quality application, I’d probably choose a language like php, python, or perl which have nice xml parsing stacks—but for something quick and dirty that works anywhere that you have curl and a bash environment this fits the bill.

Introducing the EWS Managed API!

$
0
0

Developing applications with Exchange Web Services just got MUCH easier, thanks to the release of the Microsoft Exchange Web Services (EWS) Managed API 1.0 Beta — a new managed-code API that's easy to learn, simple to use, and efficient to code against. Whether you're an experienced EWS developer, you’re new to Exchange development, or you’re somewhere in between, the EWS Managed API is made for you! Say goodbye to the large amounts of code and awkward patterns often required to use EWS via autogenerated proxy classes, and revel in the simplicity and efficiency of the new EWS Managed API!

Want to learn more? Check out David Claux's article Introducing the Exchange Web Services Managed API 1.0 for a full introduction to this new API. Take advantage of the conceptual material and code examples that are available in the Microsoft Exchange Web Services Managed API 1.0 Beta SDK April 2009. And keep your eye on this blog and the Exchange Developer Center in the coming months for posts and articles that explore various how-to scenarios for the EWS Managed API.

The Exchange 2010 Beta SDKs are Here!

$
0
0

The Exchange Developer Documentation team is happy to announce the release of the Exchange 2010 Beta SDKs.  That's right, I said SDKs -- as in, more than one!  For earlier product releases, all Exchange developer documentation is included in a single SDK. For Exchange 2010, documentation for each technology area is published in a separate SDK, making it quicker and easier for you to find information that you need. The following SDKs are available online for Exchange 2010 Beta:

The Exchange Web Services Managed API 1.0 SDK is also available online, and contains information that can help you use EWS to develop applications for Exchange 2007 SP1 or Exchange 2010.

To learn more about the new features for developers in Exchange 2010 Beta and the new SDKs, check out Thom Randolph's article Introducing the Exchange 2010 Beta SDKs. Also, be sure to review the Guide to Exchange 2010 Development Technologies, which explains the organization of the SDKs and contains information about the development technologies that are supported in Exchange 2010. Get going today and take advantage of the many cool new features available in Exchange 2010 Beta!


Exchange Impersonation vs. Delegate Access

$
0
0

There has been some confusion about the different methods that can be used to access a mailbox. Developers are asking: What method should I use? When should I use it? What are the differences between the different methods? This post will give you a quick comparison of the two most common ways, other than a direct log on, to access a mailbox: Exchange Impersonation and delegate access.

Exchange Impersonation vs. Delegate Access

Exchange Impersonation is used in scenarios in which a single account needs to access many accounts. Line-of-business applications that work with mail typically use Exchange Impersonation. An application can be written to display mailbox data such as number of unread items, calendar, and so on. The application can use a dedicated service account to access multiple users’ mailboxes to display their respective data.

Exchange Impersonation is different than Windows Impersonation. Windows Impersonation is an operating system concept that requires you to set Kerberos constrained delegation. Exchange Impersonation is a simpler authorization mechanism that is designed for use only within Exchange Web Services (EWS). For more information about Windows Impersonation, see Client Impersonation on MSDN.

Delegate access is used in scenarios in which there needs to be a one-to-one relationship between users. One common application of delegate access is the sharing of calendars between users, such as when an admin manages an executive’s calendar, or a when handful of individuals working on a project need to coordinate calendars.

Another example of delegate access is resource mailbox management. Resources, such as conference rooms, can be managed by one or more people. Resources are represented by mailboxes, but not in the traditional sense. Resource mailboxes do not have owners; therefore, they can only be accessed by mail-enabled users to whom delegate access is granted.

The following table lists the differences between Exchange Impersonation and delegate access.

Exchange Impersonation

Delegate Access

Administered by

Administrator

User

Used by

Exchange Web Services

Any mailbox client

Configuration

Per impersonator

Per shared mailbox

Rights

Broad

Granular

New account creation

Can be automated

ACLs stamped

Administration

An administrator is able to configure impersonation on behalf of a service account, and grant that service account impersonation rights over many mailboxes. Individual users cannot manage who does or does not have impersonation rights over their mailboxes.

Individual users can grant and remove delegate access to their own mailboxes through several mailbox clients, such as Microsoft Outlook, Outlook Web Access, or Exchange Web Services-based clients. A mailbox owner does not need administrator rights to grant another user delegate access to their mailbox.

Auditing

There is no true auditing for either Exchange Impersonation or delegate access. Any mail that is modified by using impersonation will appear to the mailbox as if it was modified by the user who was impersonated. No log is left behind of the impersonation access.

For delegate access, there is partial auditing, in that any mail that is sent by a delegate on behalf of the mailbox owner is displayed as “Sent on behalf of.”

Usage

Exchange Impersonation can only be used through Exchange Web Services. The caller (authenticated user) indicates which user they want to impersonate in the SOAP header. For more information about how to use Exchange Impersonation, see Using Exchange Impersonation on MSDN.

Delegate access can be used through any mailbox client, including Outlook and Exchange Web Services-based clients. For more information about delegate access, see Exchange Web Services and Delegate Access on MSDN.

Rights

A user or account that has been granted impersonation rights will have the same rights as the user whom they are impersonating. Typically, service accounts are given the ability to impersonate the mailbox owner. In that case, the impersonating account has full mailbox rights, just as the mailbox owner does.

With delegate access, the delegate can be granted more granular rights, up to and including full mailbox access. Delegate access can also be configured per folder, or per mailbox. For example, a user can grant the delegate read-only access to the Inbox, read-write access to a calendar folder, and so on.

Configuration

Exchange Impersonation is generally configured as one-to-many: one service account to many user accounts. You can configure an account to impersonate a broad set of users, such as an entire mailbox database. For more information about how to configure impersonation, see Configuring Exchange Impersonation on MSDN.

For delegate access, there is no option to set up a single delegate for multiple mailboxes. A relationship must be established for each user who needs to access a given mailbox.

New Accounts

You can configure Exchange Impersonation to allow new accounts that are created to automatically be impersonated by service accounts. Setting up accounts to impersonate any user within a mailbox database can reduce your configuration overhead.

You must explicitly grant delegate access for any new users who are added.

Don’t miss the Exchange 2010 Developer Webcasts!

$
0
0

We are excited about the Exchange 2010 developer experience and we think you will be too.  Over the next two weeks we’ll be doing six webcasts filled with information to help our partners and customers understand what Exchange 2010 means for them.  David, Chris and I just posted an introductory video to give you an overview of why we’re excited about Exchange 2010 and show off a cool application built on Exchange 2010 and the Exchange Web Services API.  Check out the video and then plan to attend the upcoming webcasts, where we will go much deeper into the technical details that you’ll want to know as you think about moving your applications to Exchange 2010 and Exchange Web Services.

View the webcast now- Exchange Server 2010 Development (Part 1 of 6): Migrating Applications to Exchange Web Services

View the webcast now - Exchange Server 2010 Development (Part 2 of 6): A Deep Dive into Using Autodiscover Service in Exchange Web Services

View the webcast now - Exchange Server 2010 Development (Part 3 of 6): A Deep Dive into Impersonation and Delegation in Exchange Web Services

View the webcase now - Exchange Server 2010 Development (Part 4 of 6): A Deep Dive into Exchange Web Services Notifications (Push/Pull)

View the webcast now - Exchange Server 2010 Development (Part 5 of 6): A Deep Dive into the Exchange Web Services Managed API

View the webcast now - Exchange Server 2010 Development (Part 6 of 6): Best Practices for Building Scalable Exchange Server Applications

 

Learn about the Exchange 2010 Developer Story Today!

$
0
0
We’ve just finished our 6 part series of webcasts on six key topics that developers need to know about as they start planning for moving their applications to Exchange 2010.  Those webcasts are now available as on-demand webcasts.  We've updated the webcast links below to point to our on demand videos so check them out today!  If you’d like a bit more human contact than these webcasts, then come join us at TechEd in Germany or Exchange Connections in Las Vegas next week; or the Microsoft Professional Developers Conference in LA November 17-19th where we’ll have great Exchange 2010 Web Services sessions and program managers from the Exchange Web Services team there to answer your questions and get your applications Exchange 2010-ready.

Play Exchange 2010 Mailbox Items on Your Phone By Using the EWS Managed API

$
0
0

The Unified Messaging Play-On-Phone feature is now exposed through Exchange Web Services in Microsoft Exchange Server 2010. This feature is described in the EWS schema and WSDL files. What will be of more interest to you is that the Play-on-Phone feature is available in the Exchange Web Services Managed API 1.0. Now you can create custom applications that can read your mailbox items to you on your phone. The EWS Managed API implementation is very straightforward. Additionally, if you plan to handle the XML in your code, the EWS XML is also intuitive for customers who want to construct the XML with Microsoft .NET, Java, a scripting language, or any other language that can send and receive HTTP messages.

The following example shows EWS Managed API code that requests that an item be played on a phone, gets the status of the phone call, and then disconnects the phone call.

static void PlayItemOnPhone (ExchangeService service, ItemId itemId, string dialstring)
{
    PhoneCall call = service.UnifiedMessaging.PlayOnPhone(itemId, dialstring);
    Console.WriteLine("Call Number: " + dialstring);
    Console.WriteLine("Call Status: " + call.State + "\n\r");

    // Create a timer that will start immediately. Timer will call callback every 2 seconds.
    Timer timer = new Timer(RefreshPhoneCallState, call, 0, 2000);

    Console.WriteLine("PRESS ENTER TO END THE PHONE CALL AND CALL STATUS UPDATES");
    Console.ReadLine();

    // Disconnect the phone call if it is not already disconnected.
    if (call.State != PhoneCallState.Disconnected)
    {
        call.Disconnect();
    }

    // Clean up the timer.
    timer.Dispose();
}

// Callback method for refreshing call state for the phone call.
static void RefreshPhoneCallState(object pCall)
{
    PhoneCall call = (PhoneCall) pCall;
    call.Refresh();
    Console.WriteLine("Call Status: " + call.State);
}

The  PlayItemOnPhone method example has three parameters:

  1. Service - The service binding that identifies the URL of the Exchange Web Services endpoint.
  2. ItemId – The item identifier of the item that will be played on the phone.
  3. dialstring - The dial string of the phone number on which the item is played. The dial string can be set to an SMTP address so that the item is played on Microsoft Office Communicator.

The example uses three EWS operations: PlayOnPhone, GetPhoneCallInformation, and DisconnectPhoneCall. PlayOnPhone is called once, GetPhoneCallInformation may be called many times, and DisconnectPhoneCall may never be called, as the phone call can be disconnected by simply hanging up the phone (of course).

After you are connected to your mailbox via the Play-On-Phone feature, you have an entry point to Outlook Voice Access. After the item is read to you, you can enter the Outlook Voice Access feature. For more information about Outlook Voice Access, see Getting Started with Outlook Voice Access.

Try out the EWS Managed API Play-on-Phone feature in your next EWS client application.

Combining Microsoft Exchange Web Services, Azure and Tag - Thor

$
0
0

Periodically we hear about very cool projects which leverage Exchange Web Services.  Below is a great example of a creative group of software developers coming up with great uses for Microsoft technology.  

 

Project Thor

·         Ever have someone stop by your office and need a place to meet? You make a quick pass around the building looking for an open room. You find one but you’re not sure how long it’s open… you want to book it… but what’s the alias to do that?

·         Ever hold an event and want to publish a live calendar directly  to attendees’ mobile phones, without having to create a new Web site or management application?

·         Ever need to publish a  resources calendar to anonymous users securely without having direct access to Exchange?

 

Sure, you could build a solution like this or even buy some of those cool conference room calendar displays, but what if you could turn just about any smartphone into an Exchange Calendaring device? Project Thor does it!

 

Thor is an open source project undertaken by the Minneapolis Cloud Computing User Group, led by Adam Grocholski from RBA consulting. Thor focuses on leveraging the power of Microsoft Tag, Windows Azure, and Exchange Server to allow access to  the schedules and scheduling services of Exchange on most mobile devices!  Thor is designed to be a real solution that showcases the power of cloud-based solutions coupled with on-premise software.

 

Thor allows any user with a smartphone and the MS Tag (http://www.microsoft.com/tag) applet installed to quickly access a resource schedule by just “Snapping” the tag with the phone’s camera! Thor supports both secure and anonymous access to resource schedules, as well as a wide variety of configuration options. Thor will even allow you to book the resource with a single “click”— no Outlook or Outlook Web App required!

 

Thor is implemented as an Azure-based solution, so you’ll need an Azure account to try it out. (If you really want to use it on-premise, the source code is provided).

 

Thor ships with three different providers: Exchange 2010 Interop, and Exchange 2007 Interop(which use the Exchange Web Services Managed API), and Native Web Services (which uses the EWS autogenerated proxies).

 

Give it a try! You can download the solution and code from the following Web site: http://thor.codeplex.com/releases/view/40406

Determining the Id of a Sent Message by Using Extended Properties with the EWS Managed API

$
0
0

Occasionally, an Exchange Web Services (EWS) development scenario requires that you attain the identifier of sent message. Although you may expect to find the identifier of the sent message in the XML response that’s returned from calling EmailMessage.SendAndSaveCopy(), no such information exists in the response. The following example shows the CreateItemResponse that’s returned from calling EmailMessage.SendAndSaveCopy() by using the EWS Managed API.

<m:CreateItemResponse
      xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
      xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
   <m:ResponseMessages>
      <m:CreateItemResponseMessage ResponseClass="Success">
         <m:ResponseCode>NoError</m:ResponseCode>
         <m:Items />
      </m:CreateItemResponseMessage>
   </m:ResponseMessages>
</m:CreateItemResponse>

Because EWS sends messages asynchronously, the identifier of the message that’s saved in the Sent Items folder when you call EmailMessage.SendAndSaveCopy() is not available immediately, and therefore is not included in the XML response.

So what’s a developer to do, if basic message properties like subject are not unique enough to identify the sent message? Well, have no fear, for extended properties are here! Simply stamp your e-mail message with a custom extended property when you create the message, and then use that extended property to find the message in the Sent Items folder after it has been sent.

The following code example shows you how to create a custom extended property on an e-mail message, send the message, and then find the message by searching the Sent Items folder for an item that has the specified extended property value.

// Create the message and set some basic properties.
EmailMessage message = new EmailMessage(service);
message.Subject = "Message Subject";
message.Body = "This message was sent by using the EWS Managed API.";
message.ToRecipients.Add("User1@example.com");

// Create a custom extended property and add it to the message.
Guid myPropertySetId = new Guid("{20B5C09F-7CAD-44c6-BDBF-8FCBEEA08544}");
ExtendedPropertyDefinition myExtendedPropertyDefinition = new ExtendedPropertyDefinition(myPropertySetId, "MyExtendedPropertyName", MapiPropertyType.String);
message.SetExtendedProperty(myExtendedPropertyDefinition, "MyExtendedPropertyValue");

// Send the message and save a copy.
message.SendAndSaveCopy();

// Wait one second (while EWS sends and saves the message).
System.Threading.Thread.Sleep(1000);

// Now, find the saved copy of the message by using the custom extended property.
ItemView view = new ItemView(5);
SearchFilter searchFilter = new SearchFilter.IsEqualTo(myExtendedPropertyDefinition, "MyExtendedPropertyValue");
view.PropertySet = new PropertySet(BasePropertySet.IdOnly, ItemSchema.Subject, myExtendedPropertyDefinition);
FindItemsResults<Item> findResults = service.FindItems(WellKnownFolderName.SentItems, searchFilter, view);

// Process results.
foreach (Item myItem in findResults.Items)
{
   if (myItem is EmailMessage)
   {
      EmailMessage em = myItem as EmailMessage;
      Console.WriteLine(em.Subject);
      Console.WriteLine(em.Id.UniqueId);
   }
}

Note: The string value that is used to instantiate the Guid in this example was generated by using guidgen.exe within Microsoft Visual Studio 2008, but you can also use other Guid generation tools.

The following is the XML request that is generated by calling FindItems in the above code example.

<m:FindItem Traversal="Shallow">
   <m:ItemShape>
      <t:BaseShape>IdOnly</t:BaseShape>
      <t:AdditionalProperties>
         <t:FieldURI FieldURI="item:Subject" />
         <t:ExtendedFieldURI PropertySetId="20b5c09f-7cad-44c6-bdbf-8fcbeea08544" PropertyName="MyExtendedPropertyName" PropertyType="String" />
      </t:AdditionalProperties>
   </m:ItemShape>
   <m:IndexedPageItemView MaxEntriesReturned="5" Offset="0" BasePoint="Beginning" />
   <m:Restriction>
      <t:IsEqualTo>
         <t:ExtendedFieldURI PropertySetId="20b5c09f-7cad-44c6-bdbf-8fcbeea08544" PropertyName="MyExtendedPropertyName" PropertyType="String" />
         <t:FieldURIOrConstant>
            <t:Constant Value="MyExtendedPropertyValue" />
         </t:FieldURIOrConstant>
      </t:IsEqualTo>
   </m:Restriction>
   <m:ParentFolderIds>
      <t:DistinguishedFolderId Id="sentitems" />
   </m:ParentFolderIds>
</m:FindItem>

As the following XML response shows, the e-mail message that was created in the code example above is successfully located by using the custom extended property that was set when the e-mail message was created.

<m:FindItemResponse
      xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
      xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
   <m:ResponseMessages>
      <m:FindItemResponseMessage ResponseClass="Success">
         <m:ResponseCode>NoError</m:ResponseCode>
         <m:RootFolder IndexedPagingOffset="1" TotalItemsInView="1" IncludesLastItemInRange="true">
            <t:Items>
               <t:Message>
                  <t:ItemId Id="aeBAAA=" ChangeKey="CQAAA+s" />
                  <t:Subject>Message Subject</t:Subject>
                  <t:ExtendedProperty>
                     <t:ExtendedFieldURI PropertySetId="20b5c09f-7cad-44c6-bdbf-8fcbeea08544" PropertyName="MyExtendedPropertyName" PropertyType="String" />
                     <t:Value>MyExtendedPropertyValue</t:Value>
                  </t:ExtendedProperty>
               </t:Message>
            </t:Items>
         </m:RootFolder>
      </m:FindItemResponseMessage>
   </m:ResponseMessages>
</m:FindItemResponse>

Want to learn more about working with extended properties and search in the EWS Managed API? Check out the code examples that are available in the Working with Extended Properties and Working with Search sections of the Microsoft Exchange Web Services Managed API 1.0 SDK.

Exchange Server 2010 SDKs March 2010 Update

$
0
0
We’ve just posted updates for many of the Exchange 2010 SDKs, and even added a new one! ...(read more)

Budget Snapshots in the IIS Logs

$
0
0

A few components (Outlook Web App, EAS, and EWS) log budget snapshot information to the IIS logs. EWS, notably, includes both a start and an end snapshot. Here is an example of an IIS log entry for EWS (lines are broken up to make it more readable):


2010-03-09 15:15:12 XX.XXX.XX.X POST /ews/Exchange.asmx ;RC:bfe35012-30fd-499e-90d6-552d0ca89fab;
Init>>Conn:0,AD:30000/30000/0%,CAS:54000/54000/0%,AB:30000/30000/0%,RPC:36000/36000/0%,FC:1000/0,Hash:14366112,Sub:20/0;
SoapAction=m:GetDelegate;Version=1;RpcC=14;RpcL=687;LdapC=0;LdapL=0;
End(17156.25ms)>>Conn:3,AD:30000/30000/0%,CAS:54000/36907/28%,AB:30000/30000/0%,RPC:36000/35985/0%,FC:1000/0,Hash:14366112,Sub:20/0;
443 Domain\User XX.XX.XXX.XX - 200 0 0 17468

I am not going to go into a lot of detail regarding all the information here at this point, but I do want to point out a few things.

The "Init" section indicates what the user’s throttling budget looked like when the call began, whereas the "End" section indicates what the user’s throttling budget looked like when the call ended.

You may be tempted to assume that the change in budget between Init and End was due only to this GetDelegate call. However, budgets take into account concurrent requests. So, if you have a number of client threads hitting Exchange for user X, a single budget actually tracks all this information. The end result is that each of these IIS logs is a snapshot that takes into consideration ALL the request threads that are currently accessing the budget.

So, for example, on this simple GetDelegate call, the initial connection count was zero and the ending connection count is 3. It would be erroneous to assume that GetDelegate created multiple connections. Instead, you would need to examine the IIS logs for the current user and see which ones overlap the current GetDelegate call. Then you can determine where those extra connections came from.

A few quick acronym helps…
RC – Request Correlation – used by Microsoft support. Enables them to correlate IIS log entries with server traces.
Conn – Connections/Concurrency (represents MaxConcurrency).
AD – Active Directory (represents PercentTimeInAD).
CAS – Client Access server (represents PercentTimeInCAS).
AB – Address Book (represents PercentTimeInAddressBook).
RPC – Remote Procedure Call (represents PercentTimeInMailboxRPC).
FC – Find Count Limit (how many records can be returned in a single paged FindItem/FindFolder call).
Sub – Number of active subscriptions (push or pull).
Hash – Hash code of the budget. You can ignore this.

You will also notice the following format in both the Init and End sections: X/Y/Z%

X - Total number of msec allowed per minute as defined by the active throttling policy.
Y – The remaining time in the budget for this policy part.
Z – The "effective percent" that represents how much of the policy the current budget has used.

David Sterling
Exchange Web Services
Inside Microsoft Exchange Server 2007 Web Services

Throttling Policies and CPUStartPercent

$
0
0

Throttling policies have this funny parameter called CPUStartPercent. This parameter defines the starting CPU use percentage at which Exchange will begin delaying inbound requests.  EWS, Exchange Active Sync, POP and IMAP honor the CPU Start Percent value in Microsoft Exchange Server 2010.

Three (no, five!) things to keep in mind:
1. The sampled CPU percent is across all CPUs. So at a CPUStartPercent of 75%, it (the process in question) would have to be using 75% of ALL CPUs for sleep throttling to kick in.
2. The sampling logic is an average over roughly a 10 second rolling window. This keeps us from responding to quick spikes in CPU.
3. This parameter is *per throttling policy*. This means that you could assign a different CPU start percent for Jane than you do for John. This is particularly useful if you have a service account whose work is more important than your ordinary user and where you just don't care if it taxes the system. Make wise decisions about this one, though, as a heavily taxed EWS will affect the user experience for someone using Outlook Web App (for example).
4. This delay is capped at 500 msec at a theoretical 100% CPU usage. However, this is *per* check. If you pass in a batch EWS request to get 100 items, it will check the CPU usage 100 times (once per item) for a maximum sleep of 50 sec... Keep that in mind :). Before you freak out about this, note that the operating system will do this anyway when it becomes overtaxed, just in a more non-deterministic fashion.
5. The delay time is linearly proportional to CPU usage. At CPUStartPercent, the delay is 0 (a thread yield) and increases linearly up to 500 msec at 100% CPU usage.

How can you determine if you are actually getting delayed due to sleep throttling? On the Exchange Client Access server, look at the MSExchange Throttling | Average Thread Sleep Time performance counter for the process you are interested in. It will give you an idea as to whether your requests are being affected by sleep throttling.

David Sterling
Exchange Web Services
Inside Microsoft Exchange Server 2007 Web Services

Throttling Policies and the EWSFindCountLimit

$
0
0

One of my favorite Exchange Web Services (EWS) methods is FindItem, primarily because it was the first Web method I wrote when I joined the EWS team long, long ago. Since then, it has undergone lots of optimizations, feature changes, and so on, to make it what it is today. One of the Exchange 2010 changes to FindItem (and FindFolder) is protective in nature – Exchange doesn’t want to drown a Client Access server just because someone decides to pull down the entire contents of their mailbox. This protective change is governed by the EWSFindCountLimit throttling policy parameter.

When a FindItem request comes in and the caller is authenticated, EWS obtains the caller’s budget. Every item (or folder in the case of FindFolder) that EWS processes for the current FindItem request is counted against the budget’s EWSFindCountLimit. As soon as the response is sent back to the caller, the find count charge for the current call is released. Why do we do this? Because items and folders that are waiting to be returned in a response take up memory on the Client Access server.

You will soon discover that budgets have a larger scope than a single request. If a caller makes two concurrent EWS FindItem requests that return 10 items each, the EWSFindCountLimit charge against that caller’s *single* budget is…20. When the first request returns, it will drop to 10 (because those items can now be garbage collected) and then when the second request returns it will drop to 0. It should be relatively obvious that we are trying to limit the caller’s memory footprint on the Client Access server.

What happens, though, when a caller reaches the limit? Well, that depends on whether the caller is being a “good EWS citizen”. And what makes an EWS citizen “good”? Well, in the context of EWSFindCountLimit, a good EWS citizen will do all their FindItem calls by using paging rather than by requesting the entire result set each time. Assume, for a moment, that the EWSFindCountLimit value is 1000 and a bad EWS citizen makes a FindItem call without paging. Let’s further say that the query will return 1001 items. EWS certainly can’t truncate the results, as the caller is expecting, to receive ALL the data back. And EWS can’t turn a non-paged FindItem call into a paged one, as the caller would not expect to check for such a response. So what does EWS do? If the call has a RequestServerVersion that is earlier than Exchange2010, you will receive a failure response with an error code of ErrorServerBusy. If your RequestServerVersion is Exchange2010, you will get back the following response:

<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <m:FindItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <m:ResponseMessages>
      <m:FindItemResponseMessage ResponseClass="Error">
        <m:MessageText>You have exceeded the maximum number of objects that can be returned for the find operation. Use paging to reduce the result size and try your request again.</m:MessageText>
        <m:ResponseCode>ErrorExceededFindCountLimit</m:ResponseCode>
        <m:DescriptiveLinkKey>0</m:DescriptiveLinkKey>
        <m:MessageXml>
          <t:Value Name="PolicyLimit">1000</t:Value>
        </m:MessageXml>
      </m:FindItemResponseMessage>
    </m:ResponseMessages>
  </m:FindItemResponse>
</s:Body>

Very interesting. For kicks, let’s reduce the EWSFindCountLimit and cycle IIS to pick up the changes (ah yes, the joys of having your own test box to beat upon). Open the Exchange 2010 Management Console as an Exchange Admin and run the following (New-ThrottlingPolicy is only available to administrators, for obvious reasons):

New-ThrottlingPolicy –Name “FooPolicy” –EWSFindCountLimit 1
Set-Mailbox JohnDoe –ThrottlingPolicy FooPolicy
iisreset

Now, on my test box, I created 6 email messages in John Doe’s Drafts folder.  Let’s call FindItem again, but use indexed paging.  Here is my request:

<soap:Header>
    <t:RequestServerVersion Version="Exchange2010"/>
</soap:Header>
<soap:Body>
<FindItem xmlns="http://schemas.microsoft.com/exchange/services/2006/messages"
           xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" Traversal="Shallow">
    <ItemShape>
        <t:BaseShape>IdOnly</t:BaseShape>
        <t:AdditionalProperties>
            <t:FieldURI FieldURI="item:Subject"/>
        </t:AdditionalProperties>
    </ItemShape>
    <IndexedPageItemView BasePoint="Beginning" Offset="0" MaxEntriesReturned="10000"/>
    <ParentFolderIds>
           <t:DistinguishedFolderId Id="drafts"/>              
        </ParentFolderIds>
</FindItem>

And the response…

<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <m:FindItemResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
    <m:ResponseMessages>
      <m:FindItemResponseMessage ResponseClass="Success">
        <m:ResponseCode>NoError</m:ResponseCode>
        <m:RootFolder IndexedPagingOffset="1" TotalItemsInView="6" IncludesLastItemInRange="false">
          <t:Items>
            <t:Message>
              <t:ItemId Id="AAMkA…"/>
              <t:Subject>Message5</t:Subject>
            </t:Message>
          </t:Items>
        </m:RootFolder>
      </m:FindItemResponseMessage>
    </m:ResponseMessages>
  </m:FindItemResponse>
</s:Body>

Whoa – wait a second! There were 6 messages to return, I asked for 10000, but it only returned 1 of them to me! What happened? Well, given that the caller’s EWSFindCountLimit is 1, EWS will NOT return more than 1 record to the user (at a time). However, because the caller was a good Exchange citizen and made a paged request, EWS can “fix up” the result because the user will (read: should) understand that EWS might not return ALL the items. The caller will instead look at the IncludesLastItemInRange attribute and, if it is false, make another FindItem request with the new Offset and continue until IncludesLastItemInRange returns true. If this behavior seems odd to you, consider that this is exactly how the various network streams in the Microsoft .NET framework behave – you continue reading from the stream until the stream reports that it has no more data to read.

So, the moral of the story is: Always use a paging mechanism when calling FindItem or FindFolder. Wisely, the Exchange Web Services Managed API forces you to do so by requiring an ItemView to be passed into FindItem:

service.FindItems(new FolderId(WellKnownFolderName.Drafts), new ItemView(10000));

Now that you know, there is no excuse for failing to use a page view :)

David Sterling
Exchange Web Services
Inside Microsoft Exchange Server 2007 Web Services

Throttling Policy Fallback Logic

$
0
0

The throttling framework is intended to protect Exchange resources, so if it is going to "fail", it needs to do so in a safe and predictable way. Let's say that Ken Malcolmson is assigned to non-default throttling policy XYZ. Unfortunately, an Active Directory elf climbed into your domain controller and scrambled things around a bit. So, when Exchange Web Services (EWS) (or some other process) tries to load policy XYZ, it fails. Or does it? Actually, it fails along a fallback path.

If the non-default policy is corrupt or missing, it will first fall back to the default throttling policy for the organization in question. Aha! What if the default policy is corrupt? Well, then it falls back to a special policy defined in code called the "fallback policy". Given that this policy is embedded in the Exchange assemblies, there is little chance that such a read will fail.

What are the values of the fallback policy? They are the exact values that default policies are assigned when Exchange is first installed.


One interesting thing about the fallback policy is that it will also be applied to authenticated callers that don’t fall neatly into an organization. Computer accounts, cross-forest contacts, typical Active Directory users (with no mailboxes), etc… will all be given budgets based on the fallback policy, so Exchange is protected against such activity. The downside to this is that because the fallback policy is defined in code, there is no way to modify the policy values for any such accounts.

David Sterling
Exchange Web Services
Inside Microsoft Exchange Server 2007 Web Services

Throttling Policies and Caches

$
0
0

So, you decide that you want to edit a throttling policy. In the Exchange Management Shell, you run Set-ThrottlingPolicy and set some odd parameter to a new value. Then you make your EWS/Outlook Web App/etc. call and notice that the results have not taken effect. Bummer!


Slightly miffed, you open up the Exchange Management Shell again and call Get-ThrottlingPolicy, and lo, the policy was indeed changed. Why didn't Exchange pick up the policy??


Welcome to the world of caching. The throttling policy framework that Exchange uses works off a "frequency of use" cache. By default, when a policy is first accessed, the process that is using that policy will load it from Active Directory and stick it in a process-wide cache for a *minimum* of 5 minutes. If no one else in that process accesses that policy from the cache, it will expire after 5 minutes so that any future calls will pick up the new data from Active Directory. However, if that policy *is* used over and over and over again, it will extend the life of that policy in the cache up to 15 minutes. After 15 minutes, the policy will expire and an up-to-date version will be loaded.

The results:

1. You cannot expect policy updates to immediately be picked up by an Exchange process. No special keys, flags, calls, or whining will help.
2. If you can wait, the policy will automatically be picked up after 15 minutes, and possibly sooner - no need to cycle the process.
3. If you cannot wait for the 15 minutes to pass, you will need to cycle the process.
4. I have found that 15 minutes is the perfect amount of time to obtain a cup of coffee from the kitchen and to begin enjoying said beverage.

David Sterling
Exchange Web Services
Inside Microsoft Exchange Server 2007 Web Services

Viewing all 108 articles
Browse latest View live




Latest Images