將 WCF Web HTTP 格式化
WCF Web HTTP 程式設計模型可讓您動態決定服務作業傳回回應所使用的最佳格式。 兩種可用來判斷最適合格式的方法分別為:自動和明確。
自動格式化
啟用時,自動格式化會選擇傳回回應所使用的最佳格式。 此方法會透過依序檢查下列各項來判斷最佳格式:
要求訊息之 Accept 標頭中的媒體類型。
要求訊息的內容類型。
作業中的預設格式設定。
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);
}
}