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:
Os tipos de mídia no cabeçalho Accept da mensagem de solicitação.
O tipo de conteúdo da mensagem de solicitação.
A configuração de formato padrão na operação.
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);
}
}