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