WCF HTTP 204 response
I'm consuming a WCF web service from a server I have little control over. Methods not returning any data fire HTTP code 204 which is totally ok in terms of HTTP, however I have a problem with WCF itself handling the response (all other methods returning 400 work just fine).
Here is my method declaration:
[OperationContract]
[WebInvoke(UriTemplate = "methodpath/V1",
RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json,
开发者_如何学Python BodyStyle = WebMessageBodyStyle.Wrapped)]
void Operation1(
[MessageParameter(Name = "username")]
string userName,
[MessageParameter(Name = "password")]
string password);
Error I get after calling the method: CommunicationException: Error in deserializing body of reply message for operation 'Operation1'. The OperationFormatter could not deserialize any information from the Message because the Message is empty (IsEmpty = true).
Also tried with IsOneWay=true: InvalidOperationException: The one-way operation returned a non-null message with Action=''.
Here is the raw HTTP response:
HTTP/1.1 204 No Content
Set-Cookie: ...
Content-Length: 0
Connection: Close
Date: Mon, 21 Mar 2011 18:41:37 GMT
exception stack trace:
Server stack trace:
at System.ServiceModel.Dispatcher.PrimitiveOperationFormatter.DeserializeReply(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.DemultiplexingClientMessageFormatter.DeserializeReply(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.CompositeClientFormatter.DeserializeReply(Message message, Object[] parameters)
at System.ServiceModel.Dispatcher.ProxyOperationRuntime.AfterReply(ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs)
at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)
Would be grateful to anyone who has an idea how to force WCF gracefully accept the response.
I think you need to write a custom channel class. Take a look at this link Channel Model Overview
I faced the same problem as you, in a situation where I had zero control over the service code. This was the signature of the method, taken from the Service Reference Visual Studio 2010 created for me:
[System.ServiceModel.OperationContractAttribute(IsOneWay=false, Action="NotificaMessaggioAssenza")]
void NotificaMessaggioAssenza(string CodiceMessaggio, string StatoRecapito);
I got through it writing a custom message inspector that did nothing but check if the reply was empty, and if it was, replace it with an empty one of the appropriate type, inferred from Action, Namespace and method name, which ended up (after some trial and error) as being serialized as:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none">http://rti.mediaset.it/soa/Turni/RPARS/RPARS_PortType/NotificaMessaggioAssenzaResponse</Action>
</s:Header>
<s:Body>
<NotificaMessaggioAssenzaResponse xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://rti.mediaset.it/soa/Turni/RPARS" />
</s:Body>
</s:Envelope>
These links helped me a lot: 1, 2, 3, 4.
精彩评论