The ContactGroupServicesproperty on a UserEndpointinstance provides access to a ContactGroupServicesinstance. The methods and properties on the ContactGroupServicesinstance can be used to manage the endpoint owner’s contacts and groups.

Note:
The ApplicationEndpointclass has no ContactGroupServicesproperty. Consequently, only a UserEndpointinstance can be used to manage contacts and groups.

Starting a Contacts and Groups Subscription

The following code example shows how to use the ContactGroupServicesproperty on a UserEndpointinstance to start a contacts and groups subscription. Also shown in this example are implementations of a callback method named ContactGroupSubscriptionCompletedand an event handler for the NotificationReceivedevent.

Copy Code
// Set up contact and group services.
ContactGroupServices cgServices =
UserEndpoint.ContactGroupServices;
// Register for the NotificationReceived event.
cgServices.NotificationReceived += CGNotificationReceived;


try
{
  cgServices.BeginSubscribe(ContactGroupSubscriptionCompleted,
cgServices);
}
catch(InvalidOperationException)
{
  Console.WriteLine("Contact Group Subscription failed.");
}
catch(RealTimeException exception)
{
  Console.WriteLine(
	"Contact Group Subscription failed. {0}",
	exception.ToString() );
}

void ContactGroupSubscriptionCompleted(IAsyncResult asyncResult)
{
  ContactGroupServices cgServices = asyncResult.AsyncState as
ContactGroupServices;
  try
  {
	cgServices.EndSubscribe(asyncResult);
  }

  catch(PublishSubscribeException pse)
  {
	Console.WriteLine(
	"Contact Group Subscription failed. {0}",
	pse.ToString());
  }

  catch(RealTimeException exception)
  {
	Console.WriteLine(
	"Contact Group Subscription failed. {0}",
	exception.ToString());
  }
}

void CGNotificationReceived(object sender,
ContactGroupNotificationEventArgs e)
{
  if (e.FullNotification)
  {
	Console.WriteLine("Got full notification of CG.");
  }
  Console.WriteLine("Delta number for this notification = {0}",
	e.DeltaN);
  foreach(NotificationItem<Contact> notification in
e.Contacts)
  {
	if (notification.Operation == PublishOperation.Add)
	{
	Console.WriteLine("Contact Added. uri = {0} Name = [1}", 
		notification.Item.Uri, notification.Item.Name);
}
	// notification.Item.GroupIDs indicate the list of groups this
	// contact is a member of.
  }
  // Similar code for Remove and Update operations. 


  foreach(NotificationItem<Group> notification in e.Groups)
  {
	if (notification.Operation == PublishOperation.Add)
	{
	Console.WriteLine("Group Added. Name = [0} Id = {1}", 
						 notification.Item.Name,
						 notification.Item.Groupid);
}
  }
  // Similar code for Remove and Update operations.
}

After a ContactGroupServicesinstance is successfully initialized with a subscription, the application begins receiving notifications about the existing contacts and groups. After the subscription is completed, the application can add, remove, or update contacts or groups.

Adding a New Contact

The following code example shows the details involved in adding a new contact. The example also shows a callback method named AddContactCompleted.

Copy Code
try
{
  cgServices.BeginAddContact(
	 "sip:mybuddy@contoso.com", AddContactCompleted, cgServices);
}
catch(InvalidOperationException)
{
  Console.WriteLine("BeginAddContact failed due to an invalid
operation.");
}
catch(RealTimeException exception)
{
  Console.WriteLine("BeginAddContact failed.",
exception.ToString());
}

void AddContactCompleted(IAsyncResult asyncResult)
{
  ContactGroupServices cgServices = 
asyncResult.AsyncState as ContactGroupServices;
  try
  {
	cgServices.EndAddContact(cgServices);
  }
  catch(PublishSubscribeException pse)
  {
	Console.WriteLine("EndAddContact failed.", pse.ToString());
  }

  catch(RealTimeException exception)
  {
	Console.WriteLine("EndAddContact failed.",
exception.ToString());
  }
}

Updating a Contact

The application can update a contact by first retrieving the cached contact, updating its properties, and then updating the contact. The reason for this is that the contact already might have been updated due to a recent notification. The delta number of the contact is needed to successfully update the contact. If the delta number does not match, the operation fails. The retrieval of the contact is an asynchronous operation because the cache might not exist at that time, and a refresh operation might be needed from the server to obtain the contacts to satisfy the requested operation.

The cache is time-based and expires in five minutes if unused. On its next use it will be repopulated.

Copy Code
// Assume that the application wants to update the name of a
contact. 
try
{
  // Assume that the application has a simple container class for
storing information.
  MyContactOperation myContactOperation = new MyContactOperation();
  myContactOperation.Cgs = cgServices;
  myContactOperation.NewName = "updatedname";
  
  cgServices.BeginGetCachedContact(
				"sip:mybuddy@contoso.com", 
				GetCachedContactCompleted, myContactOperation);
}
catch(InvalidOperationException)
{
  Console.WriteLine("GetCachedContact operation failed.");
}
catch(RealTimeException ex)
{
  Console.WriteLine("GetCachedContact failed. {0}", ex.ToString());
}

// Callback passed as an argument in BeginGetCachedContact().
void GetCachedContactCompleted(IAsyncResult asyncResult)
{
  try
  {
	MyContactOperation myContactOperation = 
			asyncResult.AsyncState as MyContactOperation;
	Contact updateContact =   
		 
myContactOperation.Cgs.EndGetCachedContact(asyncResult);
	updateContact.Name = myContactOperation.NewName;
	try
	{
	myContactOperation.Cgs.BeginUpdateContact(
				updateContact, UpdateContactCompleted,
				myContactOperation);
}
	catch(InvalidOperationException)
	{
	Console.WriteLine("UpdateContact operation failed.");
}
	catch(RealTimeException ex)
	{
	Console.WriteLine("UpdateContact failed. {0}",
ex.ToString());
}
  }
  catch(PublishSubscribeException pse)
  {
	Console.WriteLine("GetCachedContact failed. {0}",
pse.ToString());
  }
  catch(RealTimeException ex)
  {
	Console.WriteLine("GetCachedContact failed. {0}",
ex.ToString());
  }
}

// Callback passed as an argument in BeginUpdateContact().
void UpdateContactCompleted(IAsyncResult asyncResult)
{
  try
  {
	MyContactOperation myContactOperation = 
			asyncResult.AsyncState as MyContactOperation;
	myContactOperation.Cgs.EndUpdateContact(asyncResult);
	Console.WriteLine("Contact Update succeeded.");  
  }
  catch(RealTimeException ex)
  {
	Console.WriteLine("UpdateContact failed. {0}", ex.ToString());
  }
}