Share via


Procesar mensajes de correo electrónico en lotes mediante EWS en Exchange

Obtenga información sobre cómo crear, obtener, actualizar y eliminar lotes de mensajes de correo electrónico 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 mensajes de correo electrónico 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, eliminar y enviar mensajes en lotes, se usan métodos de objeto ExchangeService , mientras que cuando se trabaja con mensajes de correo electrónico únicos, se usan métodos de objeto EmailMessage . Si usa EWS, usa las mismas operaciones para trabajar con mensajes de correo electrónico individuales y por lotes.

Tabla 1. Métodos de API administrada de EWS y operaciones de EWS para trabajar con lotes de mensajes de correo electrónico

Para Uso de este método de API administrada de EWS Uso de esta operación de EWS
Creación de mensajes de correo electrónico en lotes
ExchangeService.CreateItems
CreateItem
Obtención de mensajes de correo electrónico en lotes
ExchangeService.BindToItems
GetItem
Actualización de mensajes de correo electrónico en lotes
ExchangeService.UpdateItems
UpdateItem
Eliminación de mensajes de correo electrónico en lotes
ExchangeService.DeleteItems
DeleteItem

En este artículo, aprenderá a completar tareas básicas para lotes de mensajes de correo electrónico mediante la API administrada de EWS o EWS.

Creación de mensajes de correo electrónico en lotes mediante la API administrada de EWS

Puede crear mensajes 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 EmailMessage localmente, se agrega cada mensaje a una colección y, a continuación, se llama al método CreateItems en la colección de mensajes.

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<ItemId> CreateDraftEmailInBatch(ExchangeService service)
{
    // These are unsaved local instances of an EmailMessage 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.
    EmailMessage message1 = new EmailMessage(service);
    EmailMessage message2 = new EmailMessage(service);
    EmailMessage message3 = new EmailMessage(service);
    // Set the properties on the first message.
    message1.Subject = "Project priorities";
    message1.Body = "(1) Buy pizza, (2) Eat pizza";
    message1.ToRecipients.Add("sadie@contoso.com");
    // Set the properties on the second message.
    message2.Subject = "Company Soccer Team";
    message2.Body = "Are you interested in joining?";
    message2.ToRecipients.Add("magdalena@contoso.com");
    // Set the properties on the third message.
    message3.Subject = "Code Blast";
    message3.Body = "Are you interested in getting together to finish the methods for the ContosoLive project?";
    message3.ToRecipients.Add("mack@contoso.com");
    // Add the EmailMessage objects to a collection.
    Collection<EmailMessage> messageItems = new Collection<EmailMessage>() { message1, message2, message3 };
    // Create the batch of email messages on the server.
    // This method call results in an CreateItem call to EWS.
    ServiceResponseCollection<ServiceResponse> response = service.CreateItems(messageItems, WellKnownFolderName.Drafts, MessageDisposition.SaveOnly, 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 email messages.
    foreach (EmailMessage message in messageItems)
    {
        try
        {
            itemIds.Add(message.Id);
            Console.WriteLine("Email message '{0}' created successfully.", message.Subject);
        }
        catch (Exception ex)
        {
            // Print out the exception and the last eight characters of the item ID.
            Console.WriteLine("Exception while creating message {0}: {1}", message.Id.ToString().Substring(144), ex.Message);
        }
    }
    // Check for success of the CreateItems method call.
    if (response.OverallResult == ServiceResult.Success)
    {
            Console.WriteLine("All locally created messages were successfully saved to the Drafts folder.");
            Console.WriteLine("\r\n");
    }

    // If the method did not return success, print the result message for each email.
    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 (message {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;
}

Tenga en cuenta que el ejemplo solo guarda los mensajes en la carpeta Borradores; no envía los mensajes. Para obtener más información sobre cómo enviar los mensajes, vea Envío de mensajes de correo electrónico en lotes mediante la API administrada de EWS.

Creación de mensajes de correo electrónico en lotes mediante EWS

Puede crear mensajes de correo electrónico 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 la API administrada de EWS envía cuando se usa la API administrada de EWS para crear mensajes de correo electrónico en lotes.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
               xmlns:t="https://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 MessageDisposition="SaveOnly">
      <m:SavedItemFolderId>
        <t:DistinguishedFolderId Id="drafts" />
      </m:SavedItemFolderId>
      <m:Items>
        <t:Message>
          <t:Subject>Project priorities</t:Subject>
          <t:Body BodyType="HTML">(1) Buy pizza, (2) Eat pizza</t:Body>
          <t:ToRecipients>
            <t:Mailbox>
              <t:EmailAddress>sadie@contoso.com</t:EmailAddress>
            </t:Mailbox>
          </t:ToRecipients>
        </t:Message>
        <t:Message>
          <t:Subject>Company Soccer Team</t:Subject>
          <t:Body BodyType="HTML">Are you interested in joining?</t:Body>
          <t:ToRecipients>
            <t:Mailbox>
              <t:EmailAddress>magdalena@contoso.com</t:EmailAddress>
            </t:Mailbox>
          </t:ToRecipients>
        </t:Message>
        <t:Message>
          <t:Subject>Code Blast</t:Subject>
          <t:Body BodyType="HTML">Are you interested in getting together to finish the methods for the ContosoLive project?</t:Body>
          <t:ToRecipients>
            <t:Mailbox>
              <t:EmailAddress>mack@contoso.com</t:EmailAddress>
            </t:Mailbox>
          </t:ToRecipients>
        </t:Message>
      </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 mensajes nuevos, lo que indica que cada correo electrónico se creó y guardó correctamente.

Tenga en cuenta que el ejemplo solo guarda los mensajes en la carpeta Borradores; no envía los mensajes. Para obtener más información sobre cómo enviar los mensajes, vea Envío de mensajes de correo electrónico en lotes mediante EWS.

Envío de mensajes de correo electrónico en lotes mediante la API administrada de EWS

El mismo código se usa para enviar mensajes de correo electrónico en lotes que se usan para crear mensajes de correo electrónico en lotes, salvo que algunos de los parámetros del método CreateItems cambian. Por lo tanto, para enviar mensajes de correo electrónico mediante la API administrada de EWS, use el código que usa para crear mensajes de correo electrónico en lotes y reemplace la llamada al método CreateItems por la llamada en el ejemplo siguiente. En este ejemplo, los mensajes se crean en la carpeta Elementos enviados y la eliminación del mensaje se cambia a MessageDisposition.SendAndSaveCopy, de modo que el mensaje se envía y no solo se guarda localmente.

// Create and send the batch of email messages on the server.
// This method call results in an CreateItem call to EWS.
ServiceResponseCollection<ServiceResponse> response = service.CreateItems(messageItems, WellKnownFolderName.SentItems, MessageDisposition.SendAndSaveCopy, null);

Envío de mensajes de correo electrónico en lotes mediante EWS

El mismo código se usa para enviar mensajes de correo electrónico en lotes que se usan para crear mensajes de correo electrónico en lotes, salvo que algunos de los valores de atributo cambian para la operación CreateItem . Por lo tanto, para enviar mensajes de correo electrónico mediante EWS, use el código que usa para crear mensajes de correo electrónico en lotes y cambie el valor MessageDisposition a "SendAndSaveCopy" y cambie DistinguishedFolderId a "sentitems", como se muestra en el ejemplo de código siguiente.

<m:CreateItem MessageDisposition="SendAndSaveCopy">
  <m:SavedItemFolderId>
    <t:DistinguishedFolderId Id="sentitems" />
  </m:SavedItemFolderId>

El servidor responde a la solicitud CreateItem con un mensaje CreateItemResponse que incluye un valor ResponseCode de NoError para cada uno de los mensajes nuevos, lo que indica que cada correo electrónico se creó y envió correctamente.

Obtención de mensajes de correo electrónico en lotes mediante la API administrada de EWS

Puede obtener mensajes de correo electrónico 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<EmailMessage> BatchGetEmailItems(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, EmailMessageSchema.Subject, EmailMessageSchema.ToRecipients);
    // 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 EmailMessage objects to populate from the values that are returned by the Exchange server.
    Collection<EmailMessage> messageItems = new Collection<EmailMessage>();
    foreach (GetItemResponse getItemResponse in response)
    {
        try
        {
            Item item = getItemResponse.Item;
            EmailMessage message = (EmailMessage)item;
            messageItems.Add(message);
            // Print out confirmation and the last eight characters of the item ID.
            Console.WriteLine("Found item {0}.", message.Id.ToString().Substring(144));
        }
        catch (Exception ex)
        {
           Console.WriteLine("Exception while getting a message: {0}", ex.Message);
        }
    }
    // Check for success of the BindToItems method call.
    if (response.OverallResult == ServiceResult.Success)
    {
        Console.WriteLine("All email messages retrieved successfully.");
        Console.WriteLine("\r\n");
    }
        return messageItems;
}

Obtención de mensajes de correo electrónico en lotes mediante EWS

Puede obtener mensajes de correo electrónico 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 mensajes de correo electrónico en lotes.

Los atributos itemId y ChangeKey se acortan para mejorar la legibilidad.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
               xmlns:t="https://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="item:Subject" />
          <t:FieldURI FieldURI="message:ToRecipients" />
        </t:AdditionalProperties>
      </m:ItemShape>
      <m:ItemIds>
        <t:ItemId Id="m4NxAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKB0" />
        <t:ItemId Id="m4NyAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKB1" />
        <t:ItemId Id="m4NzAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKB2" />
      </m:ItemIds>
    </m:GetItem>
  </soap:Body>
</soap:Envelope>

El servidor responde a la solicitud GetItem con un mensaje GetItemResponse que incluye las propiedades de primera clase para cada uno de los mensajes solicitados.

Actualización de mensajes de correo electrónico en lotes mediante la API administrada de EWS

Puede obtener mensajes de correo electrónico en lotes mediante el método UpdateItems de la API administrada de EWS, como se muestra en el ejemplo siguiente.

Para obtener una lista de las propiedades de mensajes de correo electrónico que se pueden escribir, vea Email propiedades y elementos en EWS en Exchange.

Para obtener más información sobre cómo enviar un borrador de mensaje una vez actualizado, vea Envío de mensajes de correo electrónico mediante la API administrada de EWS.

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<EmailMessage> BatchUpdateEmailItems(ExchangeService service, Collection<EmailMessage> messageItems)
{
    // Update the subject of each message locally.
    foreach (EmailMessage message in messageItems)
    {
        // Update the Subject of the email.
        message.Subject = "Updated subject at " + DateTime.Now;
        // Print out confirmation with the last eight characters of the item ID and the email subject.
        Console.WriteLine("Updated local email message {0} with the subject '{1}'.", message.Id.ToString().Substring(144), message.Subject);
    }
    // Send the item updates to the server.
    // This method call results in an UpdateItem call to EWS.
    ServiceResponseCollection<UpdateItemResponse> response = service.UpdateItems(messageItems, WellKnownFolderName.Drafts, ConflictResolutionMode.AutoResolve, MessageDisposition.SaveOnly, null);
    // Check for success of the UpdateItems method call.
    if (response.OverallResult == ServiceResult.Success)
    {
        Console.WriteLine("All email messages updated successfully.\r\n");
    }
    // If the method did not return success, print the result message for each email.
    else
    {
        Console.WriteLine("All emails were not successfully saved on the server.\r\n");
        int counter = 1;
        foreach (ServiceResponse resp in response)
        {
            Console.WriteLine("Result for (message {0}): {1}", counter, resp.Result);
            Console.WriteLine("Error Code: {0}", resp.ErrorCode);
            Console.WriteLine("ErrorMessage: {0}\r\n", resp.ErrorMessage);
            counter++;
        }
    }
    return messageItems;
}

Actualización de mensajes de correo electrónico en lotes mediante EWS

Puede actualizar los mensajes de correo electrónico en lotes mediante la operación EWS GetItem , como se muestra en el ejemplo de código siguiente. Esta también es la solicitud XML que la API administrada de EWS envía cuando se usa la API administrada de EWS para actualizar los mensajes de correo electrónico en lotes.

Para obtener una lista de los elementos de mensaje de correo electrónico que se pueden escribir, vea Email propiedades y elementos en EWS en Exchange.

Para obtener más información sobre cómo enviar un borrador de mensaje después de actualizarlo, vea Envío de un borrador de mensaje de correo electrónico mediante EWS.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
               xmlns:t="https://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 MessageDisposition="SaveOnly"
                  ConflictResolution="AutoResolve">
      <m:SavedItemFolderId>
        <t:DistinguishedFolderId Id="drafts" />
      </m:SavedItemFolderId>
      <m:ItemChanges>
        <t:ItemChange>
          <t:ItemId Id="m4OVAAA="
                    ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKCy" />
          <t:Updates>
            <t:SetItemField>
              <t:FieldURI FieldURI="item:Subject" />
              <t:Message>
                <t:Subject>Updated subject at 1/17/2014 2:58:09 PM</t:Subject>
              </t:Message>
            </t:SetItemField>
          </t:Updates>
        </t:ItemChange>
        <t:ItemChange>
          <t:ItemId Id="m4OWAAA="
                    ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKCz" />
          <t:Updates>
            <t:SetItemField>
              <t:FieldURI FieldURI="item:Subject" />
              <t:Message>
                <t:Subject>Updated subject at 1/17/2014 2:58:09 PM</t:Subject>
              </t:Message>
            </t:SetItemField>
          </t:Updates>
        </t:ItemChange>
        <t:ItemChange>
          <t:ItemId Id="m4OXAAA="
                    ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKC0" />
          <t:Updates>
            <t:SetItemField>
              <t:FieldURI FieldURI="item:Subject" />
              <t:Message>
                <t:Subject>Updated subject at 1/17/2014 2:58:09 PM</t:Subject>
              </t:Message>
            </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 mensajes de correo electrónico en lotes mediante la API administrada de EWS

Puede eliminar mensajes en lotes mediante el método DeleteItems 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 void BatchDeleteEmailItems(ExchangeService service, Collection<ItemId> itemIds)
{
    // Delete the batch of email message 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("Email messages deleted successfully.\r\n");
    }
    // If the method did not return success, print a message.
    else
    {
        Console.WriteLine("Not all email messages deleted successfully.\r\n");
    }
}

Eliminación de mensajes de correo electrónico en lotes mediante EWS

Puede eliminar mensajes de correo electrónico 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 mensajes de correo electrónico en lotes.

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:m="https://schemas.microsoft.com/exchange/services/2006/messages"
               xmlns:t="https://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="m4OkAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKDE" />
        <t:ItemId Id="m4OlAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKDF" />
        <t:ItemId Id="m4OmAAA="
                  ChangeKey="CQAAABYAAAApjGm7TnMWQ5TzjbhziLL0AAF/yKDG" />
      </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 mensajes de correo electrónico de una solicitud por lotes no se pueden procesar según lo solicitado, se devuelve un error para cada mensaje de correo electrónico que ha producido un error y el resto de los correos electrónicos 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 enviar, recuperar o actualizar, o si el elemento se ha movido a otra carpeta y, por lo 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 del mensaje de correo electrónico.

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 correos electrónicos se procesaron correctamente. Si OverallResult no es igual a ServiceResult.Success, uno o varios de los correos electrónicos 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 mensajes de correo electrónico según lo solicitado. En los ejemplos de este artículo se imprimen los mensajes Result, ErrorCode y ErrorMessage para cada mensaje con error. 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 correo electrónico se procesó correctamente o Error si el correo electrónico no se procesó correctamente. En el caso de los mensajes de correo electrónico, 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