Formatação HTTP da Web do WCF
O modelo de programação HTTP da Web do WCF permite que você determine dinamicamente o melhor formato para uma operação de serviço para retornar sua resposta. Há suporte para dois métodos para determinar um formato apropriado: automático e explícito.
Formatação automática
Quando habilitada, a formatação automática escolhe o melhor formato no qual retornar a resposta. Ele determina o melhor formato verificando o seguinte, na ordem:
Os tipos de mídia no cabeçalho Aceitar 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 WCF (Windows Communication Foundation) procurará um tipo compatível. Se o cabeçalho Accept
especificar prioridades para seus tipos de mídia, eles serão honrados. Se nenhum formato adequado for encontrado no cabeçalho Accept
, 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 parâmetro ResponseFormat
dos atributos WebGetAttribute e WebInvokeAttribute. Se nenhum formato padrão for especificado na operação, o valor da propriedade DefaultOutgoingResponseFormat será usado. A formatação automática depende da propriedade AutomaticFormatSelectionEnabled. Quando esta propriedade está definida como true
, a infraestrutura WCF determina o melhor formato a ser usado. A seleção de formato automático está desabilitada por padrão para compatibilidade com versões anteriores. A seleção automática de formato pode ser habilitada programaticamente ou por meio 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 habilitada por meio da configuração. Você pode definir a propriedade AutomaticFormatSelectionEnabled diretamente no WebHttpBehavior ou usando o WebHttpEndpoint. 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 o WebHttpEndpoint.
<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 Xml ou Json. Se a propriedade Format não estiver definida explicitamente, o formato padrão da operação será usado.
O exemplo a seguir verifica o parâmetro de cadeia de caracteres de consulta de formato para um formato a ser usado. Se tiver sido especificado, ele definirá 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 dar suporte a formatos diferentes de XML ou JSON, defina sua operação para ter um tipo de retorno de Message. No código de operação, determine o formato apropriado a ser usado e, em seguida, crie um objeto Message usando um dos seguintes métodos:
WebOperationContext.CreateAtom10Response
WebOperationContext.CreateJsonResponse
WebOperationContext.CreateStreamResponse
WebOperationContext.CreateTextResponse
WebOperationContext.CreateXmlResponse
Cada um desses métodos usa conteúdo e cria uma mensagem com o formato apropriado. O método WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements
pode ser usado para obter uma lista de formatos preferenciais por parte do cliente em ordem de diminuição da 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 de resposta de criação 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);
}
}