WCF Json请求接口报错:传入消息格式为‘Raw’不符合预期
WCF JSON接口请求格式错误排查
问题背景
编写处理JSON请求与响应的WCF接口时,测试返回报错:
The incoming message has an unexpected message format 'Raw'. The expected message formats for the operation are 'Xml', 'Json'
现有代码与配置
服务契约
[OperationContract] [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest, ResponseFormat = WebMessageFormat.Json)] MyRequestResponse MyRequest(MyRequestType request);
请求实体类
public partial class MyRequestType { [JsonProperty(Required = Required.Always)] public string id; }
响应实体类
public partial class MyRequestResponse { public string dummyRes = "A response of sorts."; }
Web.config配置
<service name="emuse.Chooser.Provide.ChooserWCF.ChooserQueryService" behaviorConfiguration="JsonServiceBehaviour"> <endpoint address="" binding="webHttpBinding" contract="emuse.Chooser.Provide.ChooserWCF.IChoosQueryerQueryService" behaviorConfiguration="JsonEndpointBehaviour" /> </service> <serviceBehaviors> <behavior name="JsonServiceBehaviour"> <serviceMetadata httpGetEnabled="true" /> <serviceDebug includeExceptionDetailInFaults="true" /> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="JsonEndpointBehaviour"> <enableWebScript /> </behavior> </endpointBehaviors>
测试Curl命令
curl -X POST http://localhost/Chooser/ChooserQueryService.svc/MyRequest -H 'Content-Type:application/json' -H 'Accept:application/json' -d '{"id":1}'
问题根源
<enableWebScript />与配置冲突:该行为是为ASP.NET AJAX客户端设计的,会强制特定的请求包装规则,覆盖WebInvoke中的部分设置,导致WCF无法识别传入的JSON格式。- 请求格式与
WrappedRequest不匹配:配置WrappedRequest后,WCF期望请求体包含参数名作为外层包装;同时id定义为string类型,传入数字会触发类型不匹配。
解决方案
方案一:调整请求格式适配现有配置
修改curl命令的请求体为Wrapped格式,并将id改为字符串类型:
curl -X POST http://localhost/Chooser/ChooserQueryService.svc/MyRequest -H 'Content-Type:application/json' -H 'Accept:application/json' -d '{"request":{"id":"1"}}'
方案二:修改WCF配置使用标准WebHttp行为
替换<enableWebScript />为<webHttp />,让WebInvoke的配置生效:
<endpointBehaviors> <behavior name="JsonEndpointBehaviour"> <webHttp /> </behavior> </endpointBehaviors>
- 若保持
BodyStyle = WebMessageBodyStyle.WrappedRequest,请求体仍需用{"request":{"id":"1"}}; - 若想直接传递
{"id":"1"},可将WebInvoke中的BodyStyle改为WebMessageBodyStyle.Bare。
内容的提问来源于stack exchange,提问作者Thomas Kelly
相关产品推荐
相关产品推荐

