Showing posts with label Exchange 2007. Show all posts
Showing posts with label Exchange 2007. Show all posts

Monday, November 10, 2008

Get email address from mailbox alias using EWS

Here is a cool Exchange Web Service, Resolve Name, that you can use to get the email address from your mailbox alias.

This is a sample function:


private string GetEmailAddressFromUser(string alias)
{
try
{
// SSL Certificate validation
ServicePointManager.ServerCertificateValidationCallback =
delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
// Aceptamos el certificado sin mirar
return true;
};

// Initialize the EWS Service
ExchangeServiceBinding ewsService = new ExchangeServiceBinding();

// User's Credentials
ewsService.Credentials = new NetworkCredential(m_Service_Credential_User, m_Service_Credential_Password, m_Service_Credential_Domain);

// EWS Service URL and Proxy
ewsService.Url = m_Service_Url;
ewsService.Proxy = this.GetProxy();

// Resolve Name Parameters
ResolveNamesType resolveNamesType = new ResolveNamesType();
resolveNamesType.ReturnFullContactData = true;
resolveNamesType.UnresolvedEntry = alias;

// Invoke EWS Service
ResolveNamesResponseType response = ewsService.ResolveNames(resolveNamesType);

// Get the result
ResolveNamesResponseMessageType root =
(ResolveNamesResponseMessageType)response.ResponseMessages.Items[0];

// Check the result
if (root.ResponseClass != ResponseClassType.Success)
{
// Throw an Exception
throw new ApplicationException(string.Format("{0}.{1}.{2}", root.ResponseClass, root.ResponseCode, root.MessageText));
}
else
{
// Get the email address
return root.ResolutionSet.Resolution[0].Mailbox.EmailAddress;
}
}
catch (Exception ex)
{
throw ex;
}
}

Friday, October 24, 2008

Migrate my managed Event Sink from Exchange 2003 32bits to Exchange 2007 64bits

1) Get all 64 bit versions of the dependency files. From the Exchange 2007 64 bits server get:

- C:\Program Files\Microsoft\Exchange Server\Bin\Interop.msado28.dll
- C:\Program Files\Microsoft\Exchange Server\Bin\Interop.CDOEX.dll
- C:\Program Files\Microsoft\Exchange Server\Bin\exoledb.dll

2) Install the Exchange SDK and get C:\Program Files\Microsoft\Exchange Server 2007 SP1 SDK\August 2008\Libraries\Oledb\amd64\exevtsnk.tlb.

3) Create interop files for exoledb.dll and exevtsnk.tlb:

a.1) sn.exe -k exoledb.snk
a.2) tlbimp.exe exoledb.dll /keyfile: exoledb.snk /out: Interop.Exoledb.dll /machine:x64
b.1) sn.exe -k exevtsnk.snk
b.2) tlbimp.exe exevtsnk.tlb /keyfile: exevtsnk.snk /out: Interop.Exevtsnk.dll /machine:x64

4) Modify your Visual Studio project settings:

a.1) Go to Build -> Configuration Manager menu.
a.2) Under "Active solution platform", select "New...", then select x64 and in "Copy Settings From" select "Any CPU".
b.1) Click right button over your project, and then select Properties.
b.2) On "Application" left tab, select "Assembly Information" and check "Make COM-Visible".
b.3) On "Build" left tab, select x64 as "Platform target" and uncheck "Register for COM interop". Press "Advanced" button and check "Do not reference to mscorlib.dll".

5) Add references to your interop files (Interop.msado28.dll, Interop.CDOEX.dll, Interop.Exoledb.dll and Interop.Exevtsnk.dll).

6) Delete reference to System.Data and add references to:

- C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\System.Data.dll
- C:\WINDOWS\Microsoft.NET\Framework64\v2.0.50727\mscorlib.dll

7) Build solution and get the event sink dll (.dll).

8) Register the sink in the same way you did on the 32 bit platform: regasm.exe .dll /codebase.

9) Create the COM+ in the same way you did on the 32 bit platform.

10) Register with regevent.vbs in the same way you did on the 32 bit platform: cscript regevent.vbs add "onsave" file://./backofficestorage/domain/MBX/mailbox/calendar/RegEvent.EML

Thursday, August 28, 2008

Exchange 2007 Web Services (III): Update a calendar item (UpdateItem)

In my previous post, I explained how create a calendar item with an extended property and how find this calendar item by the extended property.

In this post, I will explain how to update this calendar item, modifying the appointment's End datetime.

This is the commented code:


public void UpdateAppointment(CalendarItemType calendarItem)
{
try
{
// Delegate to accept server certificate
ServicePointManager.ServerCertificateValidationCallback =
delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
};

// Init Web Service Instance
ExchangeServiceBinding ewsService = new ExchangeServiceBinding();

// Set credentials and URL
ewsService.Credentials = new NetworkCredential("user", "qwerty", "DOMAIN");
ewsService.Url = @"https://server.domain.com/ews/exchange.asmx";

// If we need pass through a proxy
ewsService.Proxy = new WebProxy("proxy.domain.com", true);
ewsService.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;

// Exchange properties
ewsService.RequestServerVersionValue = new RequestServerVersion();
ewsService.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;

// Initialize the instance to pass to the web service method
UpdateItemType updateItem = new UpdateItemType();
updateItem.ItemChanges = new ItemChangeType[1];
updateItem.ItemChanges[0] = new ItemChangeType();

// Set the Calendar Item's ID (the item wich will be updated)
updateItem.ItemChanges[0].Item = calendarItem.ItemId;
updateItem.ItemChanges[0].Updates = new ItemChangeDescriptionType[1];

// The instance to modify the End property
SetItemFieldType setCalendarEnd = new SetItemFieldType();

// The path to the End property
PathToUnindexedFieldType calendarEndPath = new PathToUnindexedFieldType();
calendarEndPath.FieldURI = UnindexedFieldURIType.calendarEnd;

// The new End property's value
CalendarItemType calendarEndItem = new CalendarItemType();
calendarEndItem.End = new DateTime(2008, 08, 28, 17, 00, 00);
// If no -> ErrorIncorrectUpdatePropertyCount
calendarEndItem.EndSpecified = true;

setCalendarEnd.Item = calendarEndPath;
setCalendarEnd.Item1 = calendarEndItem;

updateItem.ItemChanges[0].Updates[0] = setCalendarEnd;

// This property is required in the UpdateItem method, when we update calendar items
updateItem.SendMeetingInvitationsOrCancellations = CalendarItemUpdateOperationType.SendToNone;
updateItem.SendMeetingInvitationsOrCancellationsSpecified = true;

// Invoke the web service method
UpdateItemResponseType response = ewsService.UpdateItem(updateItem);

// Get the response
UpdateItemResponseMessageType updateItemResponse =
(UpdateItemResponseMessageType)response.ResponseMessages.Items[0];

// Check the result
if (updateItemResponse.ResponseClass != ResponseClassType.Success)
{
// An error occurs
Console.Out.WriteLine("[UPDATE ITEM RESULTS]");
Console.Out.WriteLine(updateItemResponse.ResponseClass);
Console.Out.WriteLine(updateItemResponse.ResponseCode);
Console.Out.WriteLine(updateItemResponse.MessageText);
}
else
{
// No error
Console.Out.WriteLine("[UPDATE ITEM RESULTS]");
Console.Out.WriteLine(updateItemResponse.ResponseClass);
Console.Out.WriteLine(updateItemResponse.ResponseCode);
}
}
catch (Exception ex)
{
// An unexpected error
string message = ex.Message;
Console.Out.WriteLine(string.Format("Unexpected error...{0}", message));
}
}
Pay attention to this line:

calendarEndItem.End = new DateTime(2008, 08, 28, 17, 00, 00);
calendarEndItem.EndSpecified = true;

If we don't set EndSpecified property, we will receive a confusing error code: ErrorIncorrectUpdatePropertyCount.

Exchange 2007 Web Services (II): Find a calendar item by an Extended Property (FindItem)

In my previous post, I explained how to create a calendar item in Exchange 2007 through Exchange Web Services (EWS) with an extended property (NetShowUrl).

In this post, I will show you, how to find this calendar item by this property.

Here is the commented code:


public CalendarItemType FindAppointment(String filterValue)
{
try
{
// Delegate to accept server certificate
ServicePointManager.ServerCertificateValidationCallback =
delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
};

// Init Web Service Instance
ExchangeServiceBinding ewsService = new ExchangeServiceBinding();

// Set credentials and URL
ewsService.Credentials = new NetworkCredential("user", "qwerty", "DOMAIN");
ewsService.Url = @"https://server.domain.com/ews/exchange.asmx";

// If we need pass through a proxy
ewsService.Proxy = new WebProxy("proxy.domain.com", true);
ewsService.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;

// Set Exchange properties
ewsService.RequestServerVersionValue = new RequestServerVersion();
ewsService.RequestServerVersionValue.Version = ExchangeVersionType.Exchange2007_SP1;

// Initialize the instance to pass to the web service method
FindItemType item = new FindItemType();

// Set the Calendary folder to save the item
DistinguishedFolderIdType[] folders = new DistinguishedFolderIdType[1];
folders[0] = new DistinguishedFolderIdType();
folders[0].Id = DistinguishedFolderIdNameType.calendar;
// If we need to find the another's user item
//folders[0].Mailbox = new EmailAddressType();
//folders[0].Mailbox.EmailAddress = "user1@example.com";
item.ParentFolderIds = folders;

// Extended Property by we do the search
PathToExtendedFieldType netShowUrlPath = new PathToExtendedFieldType();
Guid mapiGuid = new Guid("{00062002-0000-0000-C000-000000000046}");
netShowUrlPath.PropertySetId = mapiGuid.ToString ("D");
netShowUrlPath.PropertyId = 0x8248; // NetShowUrl
netShowUrlPath.PropertyIdSpecified = true;
netShowUrlPath.PropertyType = MapiPropertyTypeType.String;

// To get this extra property to in our search
PathToUnindexedFieldType datetimestampPath = new PathToUnindexedFieldType();
datetimestampPath.FieldURI = UnindexedFieldURIType.calendarDateTimeStamp;

// We set wich properties we want
item.ItemShape = new ItemResponseShapeType();
item.ItemShape.BaseShape = DefaultShapeNamesType.AllProperties;
item.ItemShape.AdditionalProperties = new BasePathToElementType[2];
item.ItemShape.AdditionalProperties[0] = netShowUrlPath;
item.ItemShape.AdditionalProperties[1] = datetimestampPath;

// The Filter
item.Restriction = new RestrictionType();
IsEqualToType filterNetShowUrl = new IsEqualToType();
filterNetShowUrl.FieldURIOrConstant = new FieldURIOrConstantType();
FieldURIOrConstantType netShowUrlConstanType = new FieldURIOrConstantType();
ConstantValueType netShowUrlConstantValueType = new ConstantValueType();
netShowUrlConstantValueType.Value = filterValue;
netShowUrlConstanType.Item = netShowUrlConstantValueType;
filterNetShowUrl.Item = netShowUrlPath;
filterNetShowUrl.FieldURIOrConstant = netShowUrlConstanType;
item.Restriction.Item = filterNetShowUrl;

// Invoke the web service method
FindItemResponseType response = ewsService.FindItem (item);

// Get the response
FindItemResponseMessageType findItemResponse =
(FindItemResponseMessageType)response.ResponseMessages.Items[0];

// Check the result
if (findItemResponse.ResponseClass != ResponseClassType.Success)
{
// An error occurs
Console.Out.WriteLine("[FIND ITEM RESULTS]");
Console.Out.WriteLine(findItemResponse.ResponseClass);
Console.Out.WriteLine(findItemResponse.ResponseCode);
Console.Out.WriteLine(findItemResponse.MessageText);

return null;
}
else
{
// Get the first item
ArrayOfRealItemsType arrayItems = (ArrayOfRealItemsType)findItemResponse.RootFolder.Item;
CalendarItemType appointmentItem = (CalendarItemType)arrayItems.Items[0];

// Print the item's info
Console.Out.WriteLine("[FIND ITEM RESULTS]");
Console.Out.WriteLine(appointmentItem.Start);
Console.Out.WriteLine(appointmentItem.End);
Console.Out.WriteLine(appointmentItem.Subject);
Console.Out.WriteLine(appointmentItem.Location);
Console.Out.WriteLine(appointmentItem.DateTimeStamp.ToUniversalTime().ToString());

// Return the Item
return appointmentItem;
}
}
catch (Exception ex)
{
// An unexpected error
string message = ex.Message;
Console.Out.WriteLine(string.Format("Unexpected error...{0}", message));
return null;
}
}

Exchange 2007 Web Services (I): Create a calendar item with an Extended Property (CreateItem)

Here is my code sample to create an appointment item in Exchange 2007 throug Exchange Web Services (EWS), using the CreateItem method. It's commented, I hope that is sufficient to explain how to use this Exchange 2007 feature.

Also, in this sample, I explain how to add an Extended Property to our calendar item (in next post, I'll show you how to find this calendar item through this Extended Property):


public void CreateAppointment(DateTime fecha)
{
try
{
// Delegate to accept server certificate ServicePointManager.ServerCertificateValidationCallback =
delegate(Object obj, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
{
return true;
};

// Init Web Service Instance
ExchangeServiceBinding ewsService = new ExchangeServiceBinding();

// Set credentials and URL
ewsService.Credentials = new NetworkCredential("User", "qwerty", "DOMAIN");
ewsService.Url = @"https://server.domain.com/ews/exchange.asmx";
// If we need pass through a proxy
ewsService.Proxy = new WebProxy("proxy.domain.com", true);
ewsService.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials;

// Create the appointment instance
CalendarItemType appointmentItem = new CalendarItemType();

// Set Start and End Properties
appointmentItem.Start = DateTime.Now.AddHours(-1);
appointmentItem.End = DateTime.Now.AddHours(1);

// Set Location
appointmentItem.Location = "Meeting point";

// Set the Subject
appointmentItem.Subject = "Talk about Exchange 2007";

// Set the Appointment's Body
appointmentItem.Body = new BodyType();
appointmentItem.Body.BodyType1 = BodyTypeType.Text;
appointmentItem.Body.Value = "Esto es una cita de prueba.";

// According to previous Exchange's versions
appointmentItem.ItemClass = "IPM.Appointment";

// We set an extra property
appointmentItem.DateTimeStamp = fecha;

// We set an Extended Property (NetShowUrl)
appointmentItem.ExtendedProperty = new ExtendedPropertyType[1];
appointmentItem.ExtendedProperty[0] = new ExtendedPropertyType();
PathToExtendedFieldType pathNetShowUrl = new PathToExtendedFieldType();
Guid mapiGuid = new Guid("{00062002-0000-0000-C000-000000000046}");
pathNetShowUrl.PropertySetId = mapiGuid.ToString ("D");
pathNetShowUrl.PropertyId = 0x8248;
pathNetShowUrl.PropertyIdSpecified = true;
pathNetShowUrl.PropertyType = MapiPropertyTypeType.String;
appointmentItem.ExtendedProperty[0].ExtendedFieldURI = pathNetShowUrl;
appointmentItem.ExtendedProperty[0].Item = "My NetShowUrl Property value";

// Initialize the instance to pass to the web service method
CreateItemType item = new CreateItemType();

// We add our appointment item to the parameters
item.Items = new NonEmptyArrayOfAllItemsType();
item.Items.Items = new ItemType[1];
item.Items.Items[0] = appointmentItem;

// Set the Calendary folder to save the item
DistinguishedFolderIdType calendarFolder = new DistinguishedFolderIdType();
calendarFolder.Id = DistinguishedFolderIdNameType.calendar;
calendarFolder.Mailbox = new EmailAddressType();
item.SavedItemFolderId = new TargetFolderIdType();
item.SavedItemFolderId.Item = calendarFolder;

// Set if we need to send to appointment's people and invitation
// (Required Property in CalendarItem)
item.SendMeetingInvitations = CalendarItemCreateOrDeleteOperationType.SendToNone;
item.SendMeetingInvitationsSpecified = true;

// Invoke the web service method
CreateItemResponseType response = ewsService.CreateItem(item);

// Get the response
ItemInfoResponseMessageType itemInfoResponse =
(ItemInfoResponseMessageType)response.ResponseMessages.Items[0];

// Check the result
if (itemInfoResponse.ResponseClass != ResponseClassType.Success)
{
// An error occurs
Console.Out.WriteLine("[CREATE ITEM RESULTS]");
Console.Out.WriteLine(itemInfoResponse.ResponseClass);
Console.Out.WriteLine(itemInfoResponse.ResponseCode);
Console.Out.WriteLine(itemInfoResponse.MessageText);
}
else
{
// No error
Console.Out.WriteLine("[CREATE ITEM RESULTS]");
Console.Out.WriteLine(itemInfoResponse.ResponseClass);
Console.Out.WriteLin(itemInfoResponse.ResponseCode);
}
}
catch (Exception ex)
{
// An unexpected error
string message = ex.Message;
Console.Out.WriteLine (string.Format("Unexpected error...{0}", message));
}
}