Quantcast
Channel: The Exchange Guide » Calendar Item
Viewing all articles
Browse latest Browse all 7

EWS GetItem, Calendar Item returned always has null Resources

$
0
0

I am using EWS to get push notifications about changes to room mailbox calendar folders. The notifications include item ids which I in turn use in a call to GetItem. The CalendarItemType object i get back does not have the Resources attribute set. When the calendar item is created via Outlook, this is where the room mailbox is specified. How do I get the Resources list to be included in the CalendarItem object returned from a call to GetItem?

I am using the Exchange with SP1 on the server and Visual Studio with SP1 for my development.

……………………………………..

Ok, finally figured out what is going on, after way, way too much time.

The Resources are only visible to the meeting organizer. When I opened the room mailboxes with Outlook directly, the resources are not visible there. Only as the meeting organizer could I see the Resources via Outlook. Similarly, when I set up the code to log in to EWS as the meeting organizer, and then pull the item directly from the meeting organizer’s mailbox, the Resources property was set in the returned GetItemResponse.

Apparently, the Resources property is stripped in the same fashion as BCC recipients are. If someone could explain this better than I, go for it, but I am considering this matter closed.

Kim Brandl
, , 19, 4:45 PM

……………………………………..

A few of questions for you:

- Is the calendar item being created via Outlook, OWA, or EWS?

- Are you using the EWS Managed API or proxy classes?

- What property shape are you requesting in the GetItem request (i.e., IdOnly, or Default, or AllProperties)? If possible, please post the (XML) GetItem request that’s being sent to the server.

Programming Writer, Exchange Developer Documentation Team

……………………………………..

The calendar item (meeting request) is being created with an Outlook 2003 client. The resources (room mailboxes) are being added directly to the Resources line with the Select Attendees and Resources dialog.

I am using EWS proxy classes generated by Adding Web service reference using Visual Studio .

For the property shape, I am requesting AllProperties.

The C# code to get the item is as follows:

public static ItemType GetItem(string itemId, string changeKey)
{
ItemType retItem = null;
ExchangeServiceBinding esb = GetExchangeServiceBinding();
GetItemType getItemRequest = new GetItemType();
GetItemResponseType itemResponse;

getItemRequest.ItemIds = new BaseItemIdType[] { new ItemIdType() { Id = itemId, ChangeKey = changeKey } };
getItemRequest.ItemShape = new ItemResponseShapeType();
getItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;

itemResponse = esb.GetItem(getItemRequest);

// we only asked for 1 item, should only get one back
if (itemResponse.ResponseMessages != null &&
itemResponse.ResponseMessages.Items != null &&
itemResponse.ResponseMessages.Items.Length == 1)
{
ResponseMessageType respMsg = itemResponse.ResponseMessages.Items[0];
if (respMsg.ResponseClass == ResponseClassType.Error)
{
Lgr.Log(“GetItem Error: {0}\r\n\tId: {1}”, respMsg.MessageText, itemId, MT.ERROR);
}
else if (respMsg.ResponseClass == ResponseClassType.Warning)
{
Lgr.Log(“GetItem Warning: {0}\r\n\tId: {1}”, respMsg.MessageText, itemId, MT.WARNING);
}
else
{
if (respMsg is ItemInfoResponseMessageType)
{
ItemInfoResponseMessageType iirmt = respMsg as ItemInfoResponseMessageType;
if (iirmt.Items != null && iirmt.Items.Items.Length == 1)
{
retItem = iirmt.Items.Items[0];
}
else
{
Lgr.Log(“GetItem response message no items.”, MT.ERROR);
}
}
else
{
Lgr.Log(“GetItem response message of incorrect type {0}”, respMsg.GetType().ToString(), MT.ERROR);
}

}
}
else
{
Lgr.Log(“GetItem response messages null, empty, or invalid.”, MT.ERROR);
}
return retItem;
}

public static void LogItemDetails(ItemType item)
{
#if DEBUG
if (item == null)
return;

// we only care about calendar items
if (item is CalendarItemType)
{
StringBuilder sb = new StringBuilder();
CalendarItemType mt = item as CalendarItemType;
sb.Append(“ItemType: “);
sb.Append(mt.GetType().ToString());
sb.Append(“\r\n\tUID: “);
sb.Append(mt.UID);
sb.Append(“\r\n\tId: “);
sb.Append(mt.ItemId.Id);
sb.Append(“\r\n\tSubject: “);
sb.Append(mt.Subject);
sb.Append(“\r\n\tOrganizer: “);
sb.Append(mt.Organizer.Item.Name + “[" + mt.Organizer.Item.EmailAddress + "]“);
sb.Append(“\r\n\tStart: “);
sb.Append(mt.Start.ToString());
sb.Append(“End: “);
sb.Append(mt.End.ToString());
sb.Append(“\r\n\tBody: “);
sb.Append(mt.Body.Value);
sb.Append(“\r\n\tIsRecurring: “);
sb.Append(mt.IsRecurring);
if (mt.RequiredAttendees != null)
{
sb.Append(“\r\n\tRequired Attendees: “);
foreach (AttendeeType email in mt.RequiredAttendees)
{
sb.Append(email.Mailbox.Name + “[" + email.Mailbox.EmailAddress + "];”);
}
}
if (mt.OptionalAttendees != null)
{
sb.Append(“\r\n\tOptional Attendees: “);
foreach (AttendeeType email in mt.OptionalAttendees)
{
sb.Append(email.Mailbox.Name + “[" + email.Mailbox.EmailAddress + "];”);
}
}
if (mt.Resources != null)
{
sb.Append(“\r\n\tResources: “);
foreach (AttendeeType email in mt.Resources)
{
sb.Append(email.Mailbox.Name + “[" + email.Mailbox.EmailAddress + "];”);
}
}
sb.Append(“\r\n\tIsMeeting: “);
sb.Append(mt.IsMeeting);
sb.Append(“\r\n\tItemClass: “);
sb.Append(mt.ItemClass);
Lgr.Log(sb.ToString(), MT.VERBOSE);
}
else
{
Lgr.Log(“LogItemDetails, unsupported type {0}”, item.GetType().ToString(), MT.BUG);
}
#endif
}
The credentials supplied when creating the ExchangeServiceBinding are for an service account. The service account is set up as a delegate to the room mailboxes prior to setting up for the push notification subscriptions.

……………………………………..

In the code that you provided, retItem is of type ItemType, so it doesn’t contain a property for Resources. To access the Resources property on the calendar item, try casting retItem to type CalendarItemType as shown here:

retItem = iirmt.Items.Items[0];
if (retItem is CalendarItemType)
{
CalendarItemType calItem = (CalendarItemType)retItem;
Console.WriteLine(“Resources: ” + calItem.Resources[0].Mailbox.EmailAddress);
Console.WriteLine(“Resources: ” + calItem.Resources[0].Mailbox.Name);
}

Regards,
Kim Brandl

Programming Writer, Exchange Developer Documentation Team

Kim Brandl
, , 16, 10:51 PM
Unproposed As Answer by
Kim Brandl
, , 16, 11:43 PM

……………………………………..

Kim,
I wish it were that simple. While the GetItem method does return an ItemType object, the base class for CalendarItemType, it does get cast to a CalendarItemType by the calling code – the Resources property is still always null.

Just to make sure there was no miscast anywhere, I did try the code you suggested right after the assignment to retItem – Resources is still always null.

The calling code is simply:

private void ProcessEvent(ExchangeEventArgs ee)
{
ItemType it = GetItem(ee.ItemId, ee.ChangeKey);
LogItemDetails(it);
}Any other ideas? This is not some sort of extended property that I have to explicitly ask for in addition to ‘AllProperties’ is it?

……………………………………..

Using the exact code you’ve posted here, I’m unable to reproduce the issue you describe. Whether I include the cast to CalendarItemType immediately following the assignment to retItem (as shown in my prior post) or create a calling method and have that method do the cast (as you do in ProcessEvent and LogItemDetails) — the Resources property is always populated after the cast to CalendarItemType.

The only difference in my scenario and the one that you describe is that I’ve created the meeting request by using an Outlook client, and you say you created the meeting request using an Outlook 2003 client. This leads me to believe that Outlook 2003 is storing Resources in a different property than the one Outlook (and EWS) uses. To test this theory, I’d suggest that you try to create a meeting request with a Resource by using Outlook or Outlook Web Access (if you have that available) — and run your EWS code against that meeting request to see if Resource is populated.

Programming Writer, Exchange Developer Documentation Team

……………………………………..

Do you know how I might review the XML request I am sending and the response I get back? Is it possible there is something with the service reference (proxy) generated from VS vs another way?

……………………………………..

To write the XML request and response to files, add this method to your project:

static void CreateGetItemXmlMessageTextFile(GetItemType request, GetItemResponseType response)
{
// Create a text file with the request XML.
using (StreamWriter myReqWriter = new StreamWriter(request.GetType().Name + “.xml”))
{
XmlSerializer mySerializer = new XmlSerializer(request.GetType());
mySerializer.Serialize(myReqWriter, request);
}

// Create a text file with the response XML.
using (StreamWriter myRespWriter = new StreamWriter(response.GetType().Name + “.xml”))
{
XmlSerializer mySerializer = new XmlSerializer(response.GetType());
mySerializer.Serialize(myRespWriter, response);
}
}

Then call this method after you send the request, like this:
//Send the request.
itemResponse = esb.GetItem(getItemRequest);

//Write XML Request & Response to output files.
CreateGetItemXmlMessageTextFile(getItemRequest, itemResponse);

This method will create two files in the \bin\Debug directory where your VS project resides:
– GetItemType.xml contains the request XML.
– GetItemResponseType.xml contains the response XML.

Programming Writer, Exchange Developer Documentation Team

……………………………………..

Kim,

I added logging of the request and response as requested above:

The request:




AllProperties




The response:





NoError




IPM.Appointment
Updated: OWA test subject
Normal
<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>
<meta name=”Generator” content=” Exchange Server”>
<!– converted from rtf –>
<style><!– .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } –></style>
</head>
<body>
<font face=”Arial, sans-serif” size=”2″>
<div>When: , 18, 6:30 PM-7:30 PM (GMT-06:00) Central Time (US &amp; Canada).</div>
<div>Where: location field</div>
<div>&nbsp;</div>
<div>*~*~*~*~*~*~*~*~*~*</div>
<div>&nbsp;</div>
<div><font face=”Tahoma, sans-serif”>OWA Body</font></div>
<div><font face=”Tahoma, sans-serif”>&nbsp;</font></div>
</font>
</body>
</html>

-06-17T00:02:58Z
1385
Normal
false
false
false
false
false
-06-17T00:02:58Z
-06-17T00:02:58Z








-06-18T23:30:00Z
true
15

k a job; Bob Kelly
false
en-US

false
false
false
true
true
true

-06-17T17:22:58Z
040000008200E00074C5B7101A82E0080000000010307AF8DEEEC901000000000000000010000000F754E377CD6B804E9F3DEB414465D623
-06-17T17:22:56Z
-06-18T23:30:00Z
-06-19T00:30:00Z
false
Tentative
location field
true
false
false
false
true
Single
NoResponseReceived


k a job
kjob@litwareinc.com
SMTP





k a job
kjob@litwareinc.com
SMTP

Unknown



Bob Kelly
Bob@litwareinc.com
SMTP

Unknown


0
0
PT1H
Central Standard Time
6
3
0
true





As you can see, there are no resources in the response object. This is not really helpful, as I already knew the resources property was not set in the response object, which was created by the framework by deserializing the xml response sent by EWS. If the problem is in the deserialization, we need a lower level trace that shows the xml as it is returned by EWS. If EWS is putting it in that stream, then there is a problem with the proxy or deserialization code. If it is not in that stream, EWS is for some reason not putting it there.

Would you know how to turn on tracing at a much lower level so that I can see the actual data returned by EWS?

……………………………………..

I strongly suspect that your issue is being caused by the fact that Outlook 2003 stores meeting Resources in a different manner than Outlook does. I’m by no means an Outlook expert, but based on my understanding, Outlook 2003 handles meeting Resources in an entirely different way than Outlook (and thus it would make sense that the underlying properties used to store Resource data would differ between Outlook 2003 and Outlook ). So, the question really is two-fold: 1) how/where does Outlook 2003 store meeting Resources?, and 2) how can EWS be used to access Resources belonging to a calendar item that is created with Outlook 2003? I don’t know the answers to these questions, but will do some digging and let you know what I find out.

Programming Writer, Exchange Developer Documentation Team

……………………………………..

Kim,
I have tried OWA to create a meeting request with the same results. However, if you do find there is a difference, I will need to handle that as well. Keep me posted. Thanks. I am still trying to figure out how to enable message logging at the transport level to verify the GetItem request and response messages.

……………………………………..

I can create a meeting with OWA , add a single resource, and then retrieve that meeting request via OWA and the Resources collection DOES contain the resource I added when creating the meeting. Here’s my code (practically identical to the code you’ve provided):
static void ProcessCalItem(ExchangeServiceBinding esb)
{
ItemType it = GetCalItem(esb);
LogItemDetails(it);
}

static void LogItemDetails(ItemType item)
{
if (item is CalendarItemType)
{
CalendarItemType calItem = (CalendarItemType)item;
Console.WriteLine(“Resources: ” + calItem.Resources[0].Mailbox.EmailAddress);
Console.WriteLine(“Resources: ” + calItem.Resources[0].Mailbox.Name);
}
}

static ItemType GetCalItem(ExchangeServiceBinding esb)
{
// Specify ItemId of item to retrieve
ItemIdType itemId = new ItemIdType();
itemId.Id = “AAMk…=”;

ItemType retItem = null;
GetItemType getItemRequest = new GetItemType();
GetItemResponseType itemResponse;

getItemRequest.ItemShape = new ItemResponseShapeType();
getItemRequest.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
getItemRequest.ItemIds = new BaseItemIdType[] { itemId };

itemResponse = esb.GetItem(getItemRequest);

// we only asked for 1 item, should only get one back
if (itemResponse.ResponseMessages != null &&
itemResponse.ResponseMessages.Items != null &&
itemResponse.ResponseMessages.Items.Length == 1)
{
ResponseMessageType respMsg = itemResponse.ResponseMessages.Items[0];
if (respMsg.ResponseClass == ResponseClassType.Error)
{
Console.WriteLine(“GetItem Error: {0}\r\n\tId: {1}”, respMsg.MessageText, itemId.Id);
}
else if (respMsg.ResponseClass == ResponseClassType.Warning)
{
Console.WriteLine(“GetItem Warning: {0}\r\n\tId: {1}”, respMsg.MessageText, itemId.Id);
}
else
{
if (respMsg is ItemInfoResponseMessageType)
{
ItemInfoResponseMessageType iirmt = respMsg as ItemInfoResponseMessageType;
if (iirmt.Items != null && iirmt.Items.Items.Length == 1)
{
retItem = iirmt.Items.Items[0];
}
else
{
Console.WriteLine(“GetItem response message no items.”);
}
}
else
{
Console.WriteLine(“GetItem response message of incorrect type {0}”, respMsg.GetType().ToString());
}

}
}
else
{
Console.WriteLine(“GetItem response messages null, empty, or invalid.”);
}
return retItem;
}

Programming Writer, Exchange Developer Documentation Team

……………………………………..

Note: in my prior post, I meant to say “…and then retrieve that meeting request via EWS…”

Programming Writer, Exchange Developer Documentation Team

……………………………………..

Kim,
I’ve created a meeting request with an Outlook client. The calendar item as returned by EWS STILL has null Resources property. What possibly could be getting in the way of this coming back? I have been trying to figure this out for a WEEK now with no luck. How does one inspect the actual XML requests and responses that are being transported across the wire? A little help with that might help me pinpoint where the problem is. By the way, I am using the evaluation copy of Exchange SP1 virtual machine.

Anybody?

……………………………………..

Here are a couple of options for ‘sniffing’ the HTTP traffic:

NetMon: http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=983b941d-06cb-4658-b7f6-3088333d062f

Fiddler: http://www.fiddlertool.com/fiddler/

Programming Writer, Exchange Developer Documentation Team

……………………………………..

I’ve verified the response coming back from EWS on the GetItem request does NOT have the Resources property set. I did this using Fiddler – thanks for pointing that out.

The meeting request / appointment item being returned was created using Outlook , and it definitly shows the resources in both the Select Attendees and Resources dialog as well as the Select Rooms dialog.

Are there any settings on EWS or within Exchange that might effect whether these are returned? Again, I am using the evaluation copy of Exchange SP1 that comes on a virtual machine hosted in a virtual server environment.

Are there any Exchange EWS experts out there that can help figure out why the Resources property is not being returned?

Thanks in advance!

The http response as displayed by Fiddler:

HTTP/1.1 200 OK
Date: Thu, 18 Jun 21:08:20 GMT
Server: -IIS/6.0
X-Powered-By: ASP.NET
X-AspNet-Version: 2.0.50727
Cache-Control: private, max-age=0
Content-Type: text/xml; charset=utf-8
Content-Length: 5037

NoErrorIPM.AppointmenttestNormal<html>
<head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″>
<meta name=”Generator” content=” Exchange Server”>
<!– converted from rtf –>
<style><!– .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } –></style>
</head>
<body>
<font face=”Calibri, sans-serif” size=”2″>
<div>When: , 19, 8:00 AM-8:30 AM (GMT-06:00) Central Time (US &amp; Canada).</div>
<div>Where: here</div>
<div>&nbsp;</div>
<div>*~*~*~*~*~*~*~*~*~*</div>
<div>&nbsp;</div>
<div>Asdfasdf </div>
<div>&nbsp;</div>
</font>
</body>
</html>
-06-18T18:36:35Z7101Normalfalsefalsefalsefalsefalse-06-18T18:36:35Z-06-18T18:36:35Z-06-19T13:00:00Ztrue15Kevin A. Job; Bob Kellyfalseen-USfalsefalsefalsetruetruetrue-06-18T18:36:35Z040000008200E00074C5B7101A82E00800000000405D6FC819F0C9010000000000000000100000004F3929E8A373E747AB2870ECFEA07CD8-06-18T18:36:28Z-06-19T13:00:00Z-06-19T13:30:00ZfalseTentativeheretruefalsefalsefalsetrueSingleNoResponseReceivedKevin A. Jobkjob@litwareinc.comSMTPKevin A. Jobkjob@litwareinc.comSMTPUnknownBob KellyBob@litwareinc.comSMTPUnknown00PT30M(GMT-06:00) Central Time (US & Canada)030true

……………………………………..

Ok, finally figured out what is going on, after way, way too much time.

The Resources are only visible to the meeting organizer. When I opened the room mailboxes with Outlook directly, the resources are not visible there. Only as the meeting organizer could I see the Resources via Outlook. Similarly, when I set up the code to log in to EWS as the meeting organizer, and then pull the item directly from the meeting organizer’s mailbox, the Resources property was set in the returned GetItemResponse.

Apparently, the Resources property is stripped in the same fashion as BCC recipients are. If someone could explain this better than I, go for it, but I am considering this matter closed.

Kim Brandl
, , 19, 4:45 PM


Viewing all articles
Browse latest Browse all 7

Latest Images

Trending Articles



Latest Images