WCF双绑定场景下调用SendJSON报400错误的排查求助
问题:WCF双工调用客户端返回JSON时触发400 Bad Request错误
我在使用WCF的wsDualHttpBinding和WebHttpBinding,需求是服务器通过wsDual请求调用客户端,客户端处理后返回JSON给服务器。相关配置及代码如下:
配置文件
<system.serviceModel> <services> <service name="ChatTest" behaviorConfiguration = "ChatMEXBehavior"> <endpoint address ="http://localhost:8080/ChatService" binding="wsDualHttpBinding" contract="Server.IChatService"/> <endpoint address="http://localhost:8080/JSON" binding="webHttpBinding" bindingConfiguration="webBindingService" contract="Server.IWebService" behaviorConfiguration="web"/> </service> </services> <bindings> <webHttpBinding> <binding name="webBindingService" maxReceivedMessageSize="4194304"> <security mode="None"/> </binding> </webHttpBinding> </bindings> <behaviors> <serviceBehaviors> <behavior name="ChatMEXBehavior" > <serviceMetadata httpGetEnabled="true" /> </behavior> </serviceBehaviors> <endpointBehaviors> <behavior name="web"> <webHttp/> </behavior> </endpointBehaviors> </behaviors> </system.serviceModel>
ChatClient代码
public void ServerToClient(string txt) { var json = JsonConvert.SerializeObject(txt); var content = new StringContent(json, Encoding.UTF8, "application/json"); var request = new HttpRequestMessage(HttpMethod.Post, webEndpoint); request.Content = content; webService.SendJSON(request.Content.ReadAsStringAsync().Result); }
ChatService代码
public void SendMessage(string message, String clientID) { if (callback != null && clients.ContainsKey(clientID)) { clients[clientID].ServerToClient("132413414"); } }
问题现象
单独调用ServerToClient方法可正常运行,但通过ChatService调用时,执行webService.SendJSON(request.Content.ReadAsStringAsync().Result)会报错:The remote server returned an error: 400 Bad Request (WCF)。
可能原因及解决办法
1. 同步阻塞导致死锁
wsDualHttpBinding的回调线程处于WCF同步上下文,使用.Result同步等待异步操作会引发死锁,最终触发400错误。
解决:
将ServerToClient改为异步方法,用await替代同步阻塞:
public async Task ServerToClient(string txt) { var json = JsonConvert.SerializeObject(txt); var content = new StringContent(json, Encoding.UTF8, "application/json"); await webService.SendJSONAsync(await content.ReadAsStringAsync()); }
同时更新服务契约IWebService,定义异步操作:
[OperationContract] Task SendJSON(string json);
2. JSON格式不符合服务端预期
序列化字符串后传递的是带嵌套双引号的JSON(例如"132413414"),如果服务端SendJSON方法期望接收对象而非字符串,会导致解析失败。
解决:
- 若服务端期望对象:直接序列化对应业务对象,而非单纯字符串;
- 若确实需要传递字符串:跳过额外序列化,直接传递原始内容:
public async Task ServerToClient(string txt) { var content = new StringContent(txt, Encoding.UTF8, "application/json"); await webService.SendJSONAsync(txt); }
3. WebHttpBinding操作契约配置缺失
未明确指定SendJSON操作的请求格式和HTTP方法,WCF无法正确解析请求。
解决:
给SendJSON操作添加WebInvoke属性:
[OperationContract] [WebInvoke(Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, UriTemplate = "/SendJSON")] void SendJSON(string json);
4. 消息大小超出限制
即使配置了maxReceivedMessageSize,如果JSON内容接近阈值,或字符串长度超出默认读取配额,也会触发400错误。
解决:
调大消息大小并配置readerQuotas:
<webHttpBinding> <binding name="webBindingService" maxReceivedMessageSize="8388608"> <security mode="None"/> <readerQuotas maxStringContentLength="8388608" maxArrayLength="8388608"/> </binding> </webHttpBinding>
内容的提问来源于stack exchange,提问作者Jochen Middleboroguh
相关产品推荐
相关产品推荐

