Compartir a través de


Procesar contactos en lotes mediante EWS en Exchange

Obtenga información sobre cómo crear, obtener, actualizar y eliminar lotes de contactos en una sola llamada mediante la API administrada de EWS o EWS en Exchange.

Puede usar la API administrada de EWS o EWS para trabajar con lotes de contactos con el fin de reducir el número de llamadas que realiza un cliente a un servidor exchange. Cuando se usa la API administrada de EWS para crear, obtener, actualizar y eliminar contactos en lotes, se usan métodos de objeto ExchangeService , mientras que cuando se trabaja con contactos únicos, se usan métodos de objeto Contact . Si usa EWS, usa las mismas operaciones para trabajar con un único contacto y lotes de contactos.

Tabla 1. Métodos de api administrada de EWS y operaciones de EWS para trabajar con lotes de contactos

Para Uso de este método de API administrada de EWS Uso de esta operación de EWS
Creación de contactos en lotes
ExchangeService.CreateItems
CreateItem
Obtener contactos en lotes
ExchangeService.BindToItems o ExchangeService.LoadPropertiesForItems
GetItem
Actualizar contactos en lotes
ExchangeService.UpdateItems
UpdateItem
Eliminar contactos en lotes
ExchangeService.DeleteItems
DeleteItem

En este artículo, aprenderá a completar tareas básicas para lotes de contactos mediante la API administrada de EWS o EWS.

Creación de contactos en lotes mediante la API administrada de EWS

Puede crear contactos en lotes mediante el método CreateItems de la API administrada de EWS, como se muestra en el ejemplo siguiente. En este ejemplo se crean tres objetos Contact localmente, se agrega cada contacto a una colección y, a continuación, se llama al método CreateItems en la colección de contactos.

public static Collection<ItemId> CreateContactsInBatch(ExchangeService service)
{
    // These are unsaved local instances of a Contact object.
    // Despite the required parameter of an ExchangeService object (service), no call
    // to an Exchange server is made when the objects are instantiated.
    // A call to the Exchange server is made when the service.CreateItems() method is called.
    Contact contact1 = new Contact(service);
    Contact contact2 = new Contact(service);
    Contact contact3 = new Contact(service);
    // Set the properties on the first contact.
    contact1.DisplayName = "Sadie Daniels";
    contact1.EmailAddresses[EmailAddressKey.EmailAddress1] = new EmailAddress("sadie@contoso.com");
    
    // Set the properties on the second contact.
    contact2.DisplayName = "Alfred Welker";
    contact2.EmailAddresses[EmailAddressKey.EmailAddress1] = new EmailAddress("alfred@contoso.com");
    // Set the properties on the third contact.
    contact3.DisplayName = "Hope Gross";
    contact3.EmailAddresses[EmailAddressKey.EmailAddress1] = new EmailAddress("hope@contoso.com");
    // Add the Contact objects to a collection.
    Collection<Contact> contactItems = new Collection<Contact>() { contact1, contact2, contact3 };
    // Create the batch of contacts on the server.
    // This method call results in an CreateItem call to EWS.
    ServiceResponseCollection<ServiceResponse> response = service.CreateItems(contactItems, WellKnownFolderName.Contacts, null, null);
    // Instantiate a collection of item IDs to populate from the values that are returned by the Exchange server.
    Collection<ItemId> itemIds = new Collection<ItemId>();
    // Collect the item IDs from the created contacts.
    foreach (Contact contact in contactItems)
    {
        try
        {
            itemIds.Add(contact.Id);
            Console.WriteLine("Contact '{0}' created successfully.", contact.DisplayName);
        }
        catch (Exception ex)
        {
            // Print out the exception and the last eight characters of the item ID.
            Console.WriteLine("Exception while creating contact {0}: {1}", contact.Id.ToString().Substring(144), ex.Message);
        }
    }
    // Determine whether the CreateItems method call completed successfully.
    if (response.OverallResult == ServiceResult.Success)
    {
            Console.WriteLine("All locally created contacts were successfully created in the Contacts folder.");
            Console.WriteLine("\r\n");
    }
   
    // If the method did not return success, print the result message for each contact.
    else
    {
        int counter = 1;
        foreach (ServiceResponse resp in response)
        {
            // Print out the result and the last eight characters of the item ID.
            Console.WriteLine("Result (contact {0}), id {1}: {2}", counter, itemIds[counter - 1].ToString().Substring(144), resp.Result);
            Console.WriteLine("Error Code: {0}", resp.ErrorCode);
            Console.WriteLine("ErrorMessage: {0}\r\n", resp.ErrorMessage);
            Console.WriteLine("\r\n");
            counter++;
        }
    }
    return itemIds;
}

Creación de contactos en lotes mediante EWS

Puede crear contactos en lotes mediante la operación CreateItem EWS, como se muestra en el ejemplo de código siguiente. Esta es también la solicitud XML que envía la API administrada de EWS cuando se usa la API administrada de EWS para crear contactos en lotes.

<?xml version="1.0" encoding="utf-8"?>
  <soap:Envelope 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" 
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" 
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
      <t:RequestServerVersion Version="Exchange2007_SP1" />
    </soap:Header>
    <soap:Body>
      <m:CreateItem>
        <m:SavedItemFolderId>
          <t:DistinguishedFolderId Id="contacts" />
        </m:SavedItemFolderId>
        <m:Items>
          <t:Contact>
            <t:DisplayName>Sadie Daniels</t:DisplayName>
            <t:EmailAddresses>
              <t:Entry Key="EmailAddress1">sadie@contoso.com</t:Entry>
            </t:EmailAddresses>
          </t:Contact>
          <t:Contact>
            <t:DisplayName>Alfred Welker</t:DisplayName>
            <t:EmailAddresses>
              <t:Entry Key="EmailAddress1">alfred@contoso.com</t:Entry>
            </t:EmailAddresses>
          </t:Contact>
          <t:Contact>
            <t:DisplayName>Hope Gross</t:DisplayName>
            <t:EmailAddresses>
              <t:Entry Key="EmailAddress1">hope@contoso.com</t:Entry>
            </t:EmailAddresses>
          </t:Contact>
        </m:Items>
      </m:CreateItem>
    </soap:Body>
  </soap:Envelope>

El servidor responde a la solicitud CreateItem con un mensaje CreateItemResponse que incluye un valor ResponseCode de NoError para cada uno de los nuevos contactos, lo que indica que cada contacto se creó y guardó correctamente.

Obtención de contactos en lotes mediante la API administrada de EWS

Puede obtener contactos en lotes mediante el método BindToItems de la API administrada de EWS, como se muestra en el ejemplo siguiente. En este ejemplo se supone que service es un objeto ExchangeService válido y que el usuario se ha autenticado en un servidor Exchange.

public static Collection<Contact> BatchGetContactItems(ExchangeService service, Collection<ItemId> itemIds)
        {
            // Create a property set that limits the properties returned by the Bind method to only those that are required.
            PropertySet propSet = new PropertySet(BasePropertySet.IdOnly, ContactSchema.DisplayName);
            // Get the items from the server.
            // This method call results in a GetItem call to EWS.
            ServiceResponseCollection<GetItemResponse> response = service.BindToItems(itemIds, propSet);
            // Instantiate a collection of Contact objects to populate from the values that are returned by the Exchange server.
            Collection<Contact> contactItems = new Collection<Contact>();
            foreach (GetItemResponse getItemResponse in response)
            {
                try
                {
                    Item item = getItemResponse.Item;
                    Contact contact = (Contact)item;
                    contactItems.Add(contact);
                    // Print out confirmation and the last eight characters of the item ID.
                    Console.WriteLine("Found item {0}.", contact.Id.ToString().Substring(144));
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Exception while getting a contact: {0}", ex.Message);
                }
            }
            // Check for success of the BindToItems method call.
            if (response.OverallResult == ServiceResult.Success)
            {
                Console.WriteLine("All contacts retrieved successfully.");
                Console.WriteLine("\r\n");
            }
            return contactItems;
        }

Obtener contactos en lotes mediante EWS

Puede obtener contactos en lotes mediante la operación EWS GetItem y el código del ejemplo siguiente. Esta es también la solicitud XML que la API administrada de EWS envía cuando se usa la API administrada de EWS para obtener contactos en lotes. El atributo ItemId se ha acortado para mejorar la legibilidad.

<?xml version="1.0" encoding="utf-8"?>
  <soap:Envelope 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" 
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" 
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
      <t:RequestServerVersion Version="Exchange2007_SP1" />
    </soap:Header>
    <soap:Body>
      <m:GetItem>
        <m:ItemShape>
          <t:BaseShape>IdOnly</t:BaseShape>
          <t:AdditionalProperties>
            <t:FieldURI FieldURI="contacts:DisplayName" />
          </t:AdditionalProperties>
        </m:ItemShape>
        <m:ItemIds>
          <t:ItemId Id="ceJwVAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yS" />
          <t:ItemId Id="ceJwWAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yT" />
          <t:ItemId Id="ceJwXAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yU" />
        </m:ItemIds>
      </m:GetItem>
    </soap:Body>
  </soap:Envelope>

El servidor responde a la solicitud GetItem con un mensaje GetItemResponse que incluye el identificador y el nombre para mostrar de cada uno de los contactos solicitados.

Actualizar contactos en lotes mediante la API administrada de EWS

Puede actualizar los contactos en lotes mediante el método UpdateItems de la API administrada de EWS, como se muestra en el ejemplo siguiente. En el ejemplo anterior se crea el contacto, pero no se especifica para quién trabajan. Puede usar el código de este ejemplo para actualizar todos los contactos a la vez para incluir su nombre de empresa.

En este ejemplo se supone que service es un objeto ExchangeService válido y que el usuario se ha autenticado en un servidor Exchange.

public static Collection<Contact> BatchUpdateContactItems(ExchangeService service, Collection<Contact> contactItems)
        {
            // Update the company name of each contact locally.
            foreach (Contact contact in contactItems)
            {
                // Update the company name of the contact.
                contact.CompanyName = "Contoso";
                // Print out confirmation with the last eight characters of the item ID and the contact company name.
                Console.WriteLine("Updated local contact {0} with the company name '{1}'.", contact.Id.ToString().Substring(144), contact.CompanyName);
            }
            
            // Send the item updates to the server.
            // This method call results in an UpdateItem call to EWS.
            ServiceResponseCollection<UpdateItemResponse> response = service.UpdateItems(contactItems, WellKnownFolderName.Contacts, ConflictResolutionMode.AutoResolve, null, null);
            // Verify the success of the UpdateItems method call.
            if (response.OverallResult == ServiceResult.Success)
            {
                Console.WriteLine("All contacts updated successfully.\r\n");
            }
            // If the method did not return success, print the result message for each contact.
            else
            {
                Console.WriteLine("All contacts were not successfully saved on the server.\r\n");
                int counter = 1;
                foreach (ServiceResponse resp in response)
                {
                    Console.WriteLine("Result for (contact {0}): {1}", counter, resp.Result);
                    Console.WriteLine("Error Code: {0}", resp.ErrorCode);
                    Console.WriteLine("ErrorMessage: {0}\r\n", resp.ErrorMessage);
                    counter++;
                }
            }
            return contactItems;
        }    

Actualizar contactos en lotes mediante EWS

Puede actualizar los contactos en lotes mediante la operación GetItem EWS, como se muestra en el ejemplo de código siguiente. Esta es también la solicitud XML que envía la API administrada de EWS cuando se usa la API administrada de EWS para actualizar los contactos en lotes. El atributo ItemId se ha acortado para mejorar la legibilidad.

<?xml version="1.0" encoding="utf-8"?>
  <soap:Envelope 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" 
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" 
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
      <t:RequestServerVersion Version="Exchange2007_SP1" />
    </soap:Header>
    <soap:Body>
      <m:UpdateItem ConflictResolution="AutoResolve">
        <m:SavedItemFolderId>
          <t:DistinguishedFolderId Id="contacts" />
        </m:SavedItemFolderId>
        <m:ItemChanges>
          <t:ItemChange>
            <t:ItemId Id="ceJwVAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yS" />
            <t:Updates>
              <t:SetItemField>
                <t:FieldURI FieldURI="contacts:CompanyName" />
                <t:Contact>
                  <t:CompanyName>Contoso</t:CompanyName>
                </t:Contact>
              </t:SetItemField>
            </t:Updates>
          </t:ItemChange>
          <t:ItemChange>
            <t:ItemId Id="ceJwWAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yT" />
            <t:Updates>
              <t:SetItemField>
                <t:FieldURI FieldURI="contacts:CompanyName" />
                <t:Contact>
                  <t:CompanyName>Contoso</t:CompanyName>
                </t:Contact>
              </t:SetItemField>
            </t:Updates>
          </t:ItemChange>
          <t:ItemChange>
            <t:ItemId Id="ceJwXAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yU" />
            <t:Updates>
              <t:SetItemField>
                <t:FieldURI FieldURI="contacts:CompanyName" />
                <t:Contact>
                  <t:CompanyName>Contoso</t:CompanyName>
                </t:Contact>
              </t:SetItemField>
            </t:Updates>
          </t:ItemChange>
        </m:ItemChanges>
      </m:UpdateItem>
    </soap:Body>
  </soap:Envelope>

El servidor responde a la solicitud UpdateItem con un mensaje UpdateItemResponse que incluye un valor ResponseCode de NoError, lo que indica que cada una de las actualizaciones se guardó correctamente en el servidor. Los conflictos se notifican en el elemento ConflictResult .

Eliminación de contactos en lotes mediante la API administrada de EWS

Puede eliminar contactos en lotes mediante el método DeleteItems EWS Managed API, como se muestra en el ejemplo siguiente. En este ejemplo se supone que service es un objeto ExchangeService válido y que el usuario se ha autenticado en un servidor Exchange.

public static void BatchDeleteContactItems(ExchangeService service, Collection<ItemId> itemIds)
        {
            // Delete the batch of contact objects.
            // This method call results in an DeleteItem call to EWS.
            ServiceResponseCollection<ServiceResponse> response = service.DeleteItems(itemIds, DeleteMode.SoftDelete, null, AffectedTaskOccurrence.AllOccurrences);
            // Check for success of the DeleteItems method call.
            // DeleteItems returns success even if it does not find all the item IDs.
            if (response.OverallResult == ServiceResult.Success)
            {
                Console.WriteLine("Contacts deleted successfully.\r\n");
            }
            // If the method did not return success, print a message.
            else
            {
                Console.WriteLine("Not all contacts deleted successfully.\r\n");
            }
        }

Eliminación de contactos en lotes mediante EWS

Puede eliminar contactos en lotes mediante la operación DeleteItem EWS, como se muestra en el ejemplo de código siguiente. Esta es también la solicitud XML que la API administrada de EWS envía cuando se usa la API administrada de EWS para eliminar contactos en lotes. El atributo ItemId se ha acortado para mejorar la legibilidad.

<?xml version="1.0" encoding="utf-8"?>
  <soap:Envelope 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages" 
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types" 
xmlns:soap="https://schemas.xmlsoap.org/soap/envelope/">
    <soap:Header>
      <t:RequestServerVersion Version="Exchange2007_SP1" />
    </soap:Header>
    <soap:Body>
      <m:DeleteItem DeleteType="SoftDelete" AffectedTaskOccurrences="AllOccurrences">
        <m:ItemIds>
          <t:ItemId Id="ceJwYAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yY" />
          <t:ItemId Id="ceJwZAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51yZ" />
          <t:ItemId Id="ceJwaAAA=" ChangeKey="EQAAABYAAAD2WuN+TpqwSrNP9JCCMKC0AAFc51ya" />
        </m:ItemIds>
      </m:DeleteItem>
    </soap:Body>
  </soap:Envelope>

El servidor responde a la solicitud DeleteItem con un mensaje DeleteItemResponse que incluye un valor ResponseCode de NoError para cada elemento que se quitó. Tenga en cuenta que la operación también devuelve correcto si no se encontró el identificador de elemento.

Comprobación de que un proceso por lotes se completó correctamente

Cuando uno o varios contactos de una solicitud por lotes no se pueden procesar según lo solicitado, se devuelve un error para cada contacto que ha producido un error y el resto de los contactos del lote se procesan según lo previsto. Los errores en el procesamiento por lotes pueden producirse si el elemento se eliminó y, por lo tanto, no se puede recuperar ni actualizar, o si el elemento se ha movido a otra carpeta y, por tanto, tiene un nuevo identificador de elemento y no se puede modificar con el identificador de elemento enviado. La información de esta sección muestra cómo obtener detalles de error sobre errores en el procesamiento por lotes de contactos.

Para comprobar el éxito de un proceso por lotes mediante la API administrada de EWS, puede comprobar que la propiedad OverallResult de ServiceResponseCollection es igual a ServiceResult.Success. Si es así, todos los contactos se procesaron correctamente. Si OverallResult no es igual a ServiceResult.Success, uno o varios de los contactos no se procesaron correctamente. Cada uno de los objetos devueltos en ServiceResponseCollection contiene las siguientes propiedades:

Estas propiedades contienen información sobre por qué no se pudieron procesar los contactos según lo solicitado. En los ejemplos de este artículo se imprimen los valores Result, ErrorCode y ErrorMessage de cada contacto con errores. Puede usar estos resultados para investigar el problema.

Para EWS, para comprobar el éxito de un proceso por lotes, compruebe el atributo ResponseClass para cada elemento que se está procesando. A continuación se muestra la estructura básica de ResponseMessageType, el tipo base del que se derivan todos los mensajes de respuesta.

<ResponseMessage ResponseClass="Success | Warning | Error">
            <MessageText/>
            <ResponseCode/>
            <DescriptiveLinkKey/>
            <MessageXml/>
</ResponseMessage>

El atributo ResponseClass se establece en Correcto si el contacto se procesó correctamente o Error si el contacto no se procesó correctamente. En el caso de los contactos, no encontrará una advertencia durante el procesamiento por lotes. Si ResponseClass es Correcto, el elemento ResponseCode que sigue también se establece siempre en NoError. Si ResponseClass es Error, debe comprobar los valores de los elementos MessageText, ResponseCode y MessageXml para determinar qué causó el problema. DescriptiveLinkKey no se usa actualmente.

Vea también