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 设置为或 XmlJson. 如果属性 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);
}
}