几天来,我一直在尝试满足以下要求。我希望我的 WCF API 使用单一方法处理 XML 和 JSON 请求/响应。我也知道 .net 4 支持自动格式选择,但它不像我希望的 XML 和 JSON 结构那样工作。这是我的结构:
JSON:
{
"response": {
"timestamp": "12.00AM",
"locations": {
"location": [
{
"id": "5",
"name": "hello world",
"statusid": "8"
}
]
},
"errorcode": "444"
}
}
XML:
<response>
<timestamp>12.00AM</timestamp>
<locations>
<location>
<id>5</id>
<name>hello world</name>
<statusid>8</statusid>
</location>
</locations>
<errorcode>444</errorcode>
</response>
我尝试在我的 OperationContract 中切换“BodyStyle”的值,例如对于 JSON,我必须放置 WebMessageBodyStyle.Wrapped,对于 XML,我必须根据上述结构放置 WebMessageBodyStyle.Bare。由于我希望能够使用一个 OperationContract 并根据 Content-Type 自动使用 XML/JSON 结构进行响应,我必须进行哪些更改/添加?有没有办法使用 XML 和 JSON 的代码来设置这个 BodyStyle(PS API 应该是它的方式,并且不应该能够传递任何参数,如 getvalue/{xml})?
先感谢您。
更新:以下是我的 OperationContract:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "PushNotify")]
ResponsePushNotify PushNotify(RequestPushNotifiy pushnotify);
这是数据合同:
[DataContract]
public class Test: ITest
{
responsePushNotify = new ResponsePushNotify();
ResponsePushNotify PushNotify(RequestPushNotifiy pushnotify)
{
if (Content-Type == "application/json; charset=utf-8")
{
OperationContext.Current.OutgoingMessageProperties.Add(WebBodyFormatMessageProperty.Name, new WebBodyFormatMessageProperty(WebContentFormat.Json));
}
responsePushNotify.id = "1";
responsePushNotify.value = "Hello World";
return responsePushNotify ;
}
这是建议的代码:
public class MyWebHttpBehavior : WebHttpBehavior
{
protected override IDispatchMessageFormatter GetReplyDispatchFormatter(OperationDescription operationDescription, ServiceEndpoint endpoint)
{
WebGetAttribute webGet = operationDescription.Behaviors.Find<WebGetAttribute>();
IDispatchMessageFormatter json = null, xml = null;
WebMessageFormat originalFormat = webGet.ResponseFormat;
webGet.ResponseFormat = WebMessageFormat.Json;
json = base.GetReplyDispatchFormatter(operationDescription, endpoint);
webGet.ResponseFormat = WebMessageFormat.Xml;
xml = base.GetReplyDispatchFormatter(operationDescription, endpoint);
webGet.ResponseFormat = originalFormat;
return new MyReplyDispatchMessageFormatter(json, xml);
}
}
public class MyReplyDispatchMessageFormatter : IDispatchMessageFormatter
{
IDispatchMessageFormatter jsonFormatter;
IDispatchMessageFormatter xmlFormatter;
public MyReplyDispatchMessageFormatter(IDispatchMessageFormatter jsonFormatter, IDispatchMessageFormatter xmlFormatter)
{
this.jsonFormatter = jsonFormatter;
this.xmlFormatter = xmlFormatter;
}
public void DeserializeRequest(Message message, object[] parameters)
{
throw new NotSupportedException("Used for replies only");
}
public Message SerializeReply(MessageVersion messageVersion, object[] parameters, object result)
{
IDispatchMessageFormatter formatter = this.xmlFormatter;
if (OperationContext.Current.OutgoingMessageProperties.ContainsKey(WebBodyFormatMessageProperty.Name))
{
WebBodyFormatMessageProperty webBody = (WebBodyFormatMessageProperty)OperationContext.Current.OutgoingMessageProperties[WebBodyFormatMessageProperty.Name];
if (webBody != null && webBody.Format == WebContentFormat.Json)
{
formatter = this.jsonFormatter;
}
}
return formatter.SerializeReply(messageVersion, parameters, result);
}
}
这是我的网络配置:
<?xml version="1.0"?>
<configuration>
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="true"/>
<services>
<service behaviorConfiguration="CustomBehavior" name="Service.Test">
<endpoint address="" behaviorConfiguration="web" binding="webHttpBinding" contract="Services.ITest" bindingConfiguration="general"/>
</service>
</services>
<bindings>
<webHttpBinding>
<binding name="general" closeTimeout="00:10:00" openTimeout="00:10:00" sendTimeout="00:10:00"
receiveTimeout="00:10:00" maxReceivedMessageSize="2147483647" maxBufferPoolSize="4194304"
maxBufferSize="2147483647" />
</webHttpBinding>
</bindings>
<behaviors>
<endpointBehaviors>
<behavior name="web">
<webHttp automaticFormatSelectionEnabled="true" />
</behavior>
</endpointBehaviors>
<serviceBehaviors>
<behavior name="CustomBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
</configuration>
所以现在我的问题是,如何在代码中定义我的自定义行为并将其添加到 webconfig?我需要做什么改变?另外,如果我要设置“BodyStyle = WebMessageBodyStyle.Wrapped”,我该怎么做?在哪里做?