WCF Web HTTP 形式

WCF Web HTTP プログラミング モデルでは、サービス操作で返す応答の最適な形式を動的に判断できます。 適切な形式を判断するための方法として、自動と明示的の 2 つがサポートされます。

自動書式

有効にした場合は、応答を返す最適な形式が自動選択によって選択されます。 最適な形式の判断は、次の項目をこの順序で確認することで行われます。

  1. 要求メッセージの Accept ヘッダーのメディアの種類。

  2. 要求メッセージのコンテンツの種類。

  3. その処理での既定の形式設定。

  4. WebHttpBehavior での既定の形式設定。

要求メッセージに Accept ヘッダーが含まれる場合、Windows Communication Foundation (WCF) インフラストラクチャによってサポートされる種類が検索されます。 Accept ヘッダーにメディアの種類のプロパティが指定されている場合は、それに従います。 適切な形式が Accept ヘッダーで見つからない場合は、要求メッセージのコンテンツの種類が使用されます。 適切なコンテンツの種類が指定されていない場合は、その操作の既定の形式設定が使用されます。 既定の形式は、ResponseFormatWebGetAttribute パラメーターおよび 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 の場合は、開発者が FormatXml または 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);  
    }  
}  

関連項目