Formatação HTTP da Web do WCF

O modelo de programação Web HTTP do WCF permite determinar dinamicamente o melhor formato para uma operação de serviço retornar sua resposta. Dois métodos para determinar um formato apropriado são suportados: automático e explícito.

Formatação automática

Quando ativada, a formatação automática escolhe o melhor formato para retornar a resposta. Ele determina o melhor formato verificando o seguinte, na ordem:

  1. Os tipos de mídia no cabeçalho Accept da mensagem de solicitação.

  2. O tipo de conteúdo da mensagem de solicitação.

  3. A configuração de formato padrão na operação.

  4. A configuração de formato padrão no WebHttpBehavior.

Se a mensagem de solicitação contiver um cabeçalho Accept, a infraestrutura do Windows Communication Foundation (WCF) procurará um tipo que ele suporta. Se o Accept cabeçalho especificar prioridades para seus tipos de mídia, eles serão honrados. Se nenhum formato adequado for encontrado no Accept cabeçalho, o tipo de conteúdo da mensagem de solicitação será usado. Se nenhum tipo de conteúdo adequado for especificado, a configuração de formato padrão para a operação será usada. O formato padrão é definido com o ResponseFormat parâmetro de WebGetAttributeWebInvokeAttribute e atributos. Se nenhum formato padrão for especificado na operação, o valor da DefaultOutgoingResponseFormat propriedade será usado. A formatação automática depende da AutomaticFormatSelectionEnabled propriedade. Quando essa propriedade é definida como true, a infraestrutura WCF determina o melhor formato a ser usado. A seleção automática de formato é desativada por padrão para compatibilidade com versões anteriores. A seleção automática de formatos pode ser ativada programaticamente ou através da configuração. O exemplo a seguir mostra como habilitar a seleção automática de formato no código.

// This code assumes the service name is MyService and the service contract is IMyContract
Uri baseAddress = new Uri("http://localhost:8000");  
  
WebServiceHost host = new WebServiceHost(typeof(MyService), baseAddress)  
try  
{  
   ServiceEndpoint sep = host.AddServiceEndpoint(typeof(IMyContract), new WebHttpBinding(), "");  
   // Check it see if the WebHttpBehavior already exists  
   WebHttpBehavior whb = sep.Behaviors.Find<WebHttpBehavior>();  
  
   if (whb != null)  
   {  
      whb.AutomaticFormatSelectionEnabled = true;  
   }  
   else  
   {  
      WebHttpBehavior webBehavior = new WebHttpBehavior();  
      webBehavior.AutomaticFormatSelectionEnabled = true;  
      sep.Behaviors.Add(webBehavior);  
   }  
         // Open host to start listening for messages  
   host.Open();
  
  // ...  
}  
  catch(CommunicationException ex)  
  {  
     Console.WriteLine("An exception occurred: " + ex.Message());  
  }  

A formatação automática também pode ser ativada através da configuração. Você pode definir a AutomaticFormatSelectionEnabled propriedade diretamente no ou usando o WebHttpBehaviorWebHttpEndpoint. O exemplo a seguir mostra como habilitar a seleção automática de formato no WebHttpBehavior.

<system.serviceModel>  
  <behaviors>  
    <endpointBehaviors>  
      <behavior>  
        <webHttp automaticFormatSelectionEnabled="true" />  
      </behavior>  
    </endpointBehaviors>  
  </behaviors>  
  <standardEndpoints>  
    <webHttpEndpoint>  
      <!-- the "" standard endpoint is used by WebServiceHost for auto creating a web endpoint. -->  
      <standardEndpoint name="" helpEnabled="true" />  
    </webHttpEndpoint>  
  </standardEndpoints>  
</system.serviceModel>  

O exemplo a seguir mostra como habilitar a seleção automática de formato usando WebHttpEndpointo .

<system.serviceModel>  
    <standardEndpoints>  
      <webHttpEndpoint>  
        <!-- the "" standard endpoint is used by WebServiceHost for auto creating a web endpoint. -->  
        <standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true"  />  
      </webHttpEndpoint>  
    </standardEndpoints>  
  </system.serviceModel>  

Formatação explícita

Como o nome indica, na formatação explícita o desenvolvedor determina o melhor formato a ser usado dentro do código de operação. Se o melhor formato for XML ou JSON, o desenvolvedor definirá Format como um Xml ou Json. Se a Format propriedade não estiver definida explicitamente, o formato padrão da operação será usado.

O exemplo a seguir verifica o parâmetro format query string para um formato a ser usado. Se tiver sido especificado, ele define o formato da operação usando Format.

public class Service : IService  
{  
    [WebGet]  
     public string EchoWithGet(string s)  
    {  
        // if a format query string parameter has been specified, set the response format to that. If no such
        // query string parameter exists the Accept header will be used
        string formatQueryStringValue = WebOperationContext.Current.IncomingRequest.UriTemplateMatch.QueryParameters["format"];  
        if (!string.IsNullOrEmpty(formatQueryStringValue))  
        {  
            if (formatQueryStringValue.Equals("xml", System.StringComparison.OrdinalIgnoreCase))  
            {
                WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Xml;
            }
            else if (formatQueryStringValue.Equals("json", System.StringComparison.OrdinalIgnoreCase))  
            {  
                WebOperationContext.Current.OutgoingResponse.Format = WebMessageFormat.Json;  
            }  
            else  
            {  
                throw new WebFaultException<string>($"Unsupported format '{formatQueryStringValue}'",   HttpStatusCode.BadRequest);
            }  
        }  
        return "You said " + s;  
    }  

Se você precisar oferecer suporte a formatos diferentes de XML ou JSON, defina sua operação para ter um tipo de retorno de Message. Dentro do código de operação, determine o formato apropriado a ser usado e, em seguida, crie um Message objeto usando um dos seguintes métodos:

  • WebOperationContext.CreateAtom10Response

  • WebOperationContext.CreateJsonResponse

  • WebOperationContext.CreateStreamResponse

  • WebOperationContext.CreateTextResponse

  • WebOperationContext.CreateXmlResponse

Cada um desses métodos pega o conteúdo e cria uma mensagem com o formato apropriado. O WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements método pode ser usado para obter uma lista de formatos preferidos pelo cliente em ordem decrescente de preferência. O exemplo a seguir mostra como usar WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements para determinar o formato a ser usado e, em seguida, usa o método create response apropriado para criar a mensagem de resposta.

public class Service : IService  
{  
    public Message EchoListWithGet(string list)  
    {  
        List<string> returnList = new List<string>(list.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));  
        IList<ContentType> acceptHeaderElements = WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements();  
        for (int x = 0; x < acceptHeaderElements.Count; x++)  
        {  
            string normalizedMediaType = acceptHeaderElements[x].MediaType.ToLowerInvariant();  
            switch (normalizedMediaType)  
            {  
                case "image/jpeg": return CreateJpegResponse(returnList);  
                case "application/xhtml+xml": return CreateXhtmlResponse(returnList);  
                case "application/atom+xml": return CreateAtom10Response(returnList);  
                case "application/xml": return CreateXmlResponse(returnList);  
                case "application/json": return CreateJsonResponse(returnList);  
          }  
    }  
  
    // Default response format is XML  
    return CreateXmlResponse(returnList);  
    }  
}  

Consulte também