我试图按照以下要求工作几天。我希望我的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结构,我必须做出哪些更改/添加?有没有办法使用Code和XML和JSON设置这个BodyStyle(P.S.API应该是它的方式,不应该传递任何参数,如getvalue / {xml})?
提前谢谢。
更新:下面是我的OperationContract:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "PushNotify")]
ResponsePushNotify PushNotify(RequestPushNotifiy pushnotify);
这是DataContract:
[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);
}
}
这是我的webconfig:
<?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”如何&amp;我在哪里这样做?
答案 0 :(得分:0)
我看到这个问题是很久以前发布的,但是可能对某些人有用。我在overcoder.net上找到了解决方案。您所需要做的就是为所需的输出格式生成对应的字符串,并将Stream用于结果类型。
[OperationContract]
[WebGet(UriTemplate = "test?format={format}")]
System.IO.Stream test(string format);
public System.IO.Stream test(string format)
{
ArrayList ar = new ArrayList() { 1, 2, 3 };
if (format == "text")
result = String.Join(",", ar.ToArray());
if (format == "xml")
{
result = @"<soapenv:Envelope>
<soapenv:Header/>
<soapenv:Body>
<result>";
foreach (int i in ar)
result += String.Format("\r\n <item>{0}</item>", i);
result += @"
</result>
</soapenv:Body>
</soapenv:Envelope>";
}
if (format == "json")
result = JsonConvert.SerializeObject(ar, Newtonsoft.Json.Formatting.Indented);
OutgoingWebResponseContext context = WebOperationContext.Current.OutgoingResponse;
context.ContentType = "text/plain";
return new System.IO.MemoryStream(ASCIIEncoding.Default.GetBytes(result));
}