Поделиться через


Форматирование WCF Web HTTP

Модель программирования ВЕБ-HTTP WCF позволяет динамически определять оптимальный формат операции службы для возврата ответа. Поддерживаются два метода определения соответствующего формата: автоматический и явный.

Автоматическое форматирование

При включении автоматическое форматирование выбирает оптимальный формат, в котором будет возвращен ответ. Он определяет лучший формат, проверяя следующий порядок:

  1. Типы медиа в заголовке Accept сообщения запроса.

  2. Тип контента сообщения запроса.

  3. Параметр формата по умолчанию в операции.

  4. Параметр формата по умолчанию в WebHttpBehavior.

Если сообщение запроса содержит заголовок Accept, инфраструктура Windows Communication Foundation (WCF) ищет тип, который он поддерживает. Accept Если заголовок задает приоритеты для типов медиа, они будут соблюдены. Если в заголовке Accept нет подходящего формата, используется тип контента сообщения запроса. Если не указан подходящий тип контента, используется параметр формата по умолчанию для операции. Формат по умолчанию устанавливается параметром ResponseFormat атрибутов WebGetAttribute и WebInvokeAttribute. Если для операции не указан формат по умолчанию, используется значение DefaultOutgoingResponseFormat свойства. Автоматическое форматирование зависит от AutomaticFormatSelectionEnabled свойства. Если для этого свойства задано trueзначение, инфраструктура WCF определяет оптимальный формат для использования. Автоматический выбор формата по умолчанию отключен для обеспечения обратной совместимости. Автоматическое выделение формата можно включить программным способом или с помощью конфигурации. В следующем примере показано, как включить автоматическое выделение формата в коде.

// 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());  
  }  

Автоматическое форматирование также можно включить с помощью конфигурации. Свойство можно задать AutomaticFormatSelectionEnabled непосредственно в объекте WebHttpBehavior или с помощью WebHttpEndpoint. В следующем примере показано, как включить автоматический выбор формата на элементе 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>  

В следующем примере показано, как включить автоматическое выделение формата с помощью 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>  

Явное форматирование

Как подразумевает имя, в явном форматировании разработчик определяет лучший формат, используемый в коде операции. Если лучшим форматом является XML или JSON, разработчик выбирает Format как Xml или Json. Format Если свойство не задано явным образом, используется формат операции по умолчанию.

В следующем примере проверяется параметр строки запроса, чтобы определить формат, который следует использовать. Если он указан, он задает формат операции с помощью 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;  
    }  

Если необходимо поддерживать форматы, отличные от XML или JSON, определите, что операция имеет тип возвращаемого Messageзначения. В коде операции определите подходящий формат для использования, а затем создайте Message объект с помощью одного из следующих методов:

  • WebOperationContext.CreateAtom10Response

  • WebOperationContext.CreateJsonResponse

  • WebOperationContext.CreateStreamResponse

  • WebOperationContext.CreateTextResponse

  • WebOperationContext.CreateXmlResponse

Каждый из этих методов принимает содержимое и создает сообщение с соответствующим форматом. Этот WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements метод можно использовать для получения списка форматов, предпочитаемых клиентом, в порядке уменьшения предпочтения. В следующем примере показано, как использовать WebOperationContext.Current.IncomingRequest.GetAcceptHeaderElements для определения формата использования, а затем использовать соответствующий метод создания ответа, чтобы сформировать ответное сообщение.

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);  
    }  
}  

См. также