WCF WebInvoke Body Format Error
I spent Sunday afternoon battling an odd WCF error.
System.InvalidOperationException: Incoming message for operation [your operation here] contains an unrecognized http body format value ‘Xml’. The expected body format value is ‘Raw’. This can be because a WebContentTypeMapper has not been configured on the binding. See the documentation of WebContentTypeMapper for more details.
Troubleshooting this issue sucked. Here’s the deal: WCF helpfully attempts to parse any incoming “text/xml” requests automatically. If you’ve defined the input parameter on a WebInvoke operation to be a Stream, WCF can’t bind to the method and returns an HTTP 400.
There’s two ways to solve this problem: Change the input parameter from Stream to XmlElement, or configure WCF to treat this request as Raw. I picked the former method. Carlos Figueira explains the latter method.
If folks are interested, I can post some more detail about the problem and the resolution. For now, I have to finish making things work.
Edit: So here’s the rest of the story, since Brad asked.
I wasn’t sure exactly what triggered the issue. I got this behavior with just one WebInvoke and one WebGet operation using the same URI template. What I’d done was to create a generic ObjectService that exposed the same RESTian operations for several different types of objects. The particular operation in question looked something like this:
-
[OperationContract]
-
[WebGet(UriTemplate = ItemUris.IndexXml, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
-
Stream GetListAsXml();
-
-
[OperationContract]
-
[WebInvoke(UriTemplate = ItemUris.IndexXml, Method = "POST", BodyStyle = WebMessageBodyStyle.Bare, RequestFormat = WebMessageFormat.Xml, ResponseFormat = WebMessageFormat.Xml)]
-
Stream PostListAsXml(XmlElement input);
Originally, PostListAsXml had accepted a Stream. That seemed to work in other places, but then I started noticing the InvalidOperationException messages.
I think the right way to solve this problem is to follow Carlos’ advice, and create a new WebContentTypeMapper-derived class. But I didn’t have time to figure out exactly where to plug it in, and I was afraid that I might introduce other problems. I just didn’t know enough about the inner workings of WCF to know whether that was a safe operation.
Since we hadn’t shipped the interface yet, I was free to change the return type from Stream to XmlElement for the one or two WebInvoke operations that were returning errors. Fewer lines of code needed to change, and I knew I wouldn’t break anything else.
Of course, I’m probably just setting myself up for more pain down the road, but sometimes you just need to get things done, y’know?
Anyway, since I’ll likely revisit this decision in a later release, I’d love to hear what other folks did in this situation.
No related posts.
Hey Dean,
I’m running into this same error and am wondering why you went the XmlElement way instead of getting WCF to treat the request as Raw?
By the way, did this error come about if you only had one WebInvoke on the service, or only after you added multiple WebInvokes?
Thanks,
Brad
Hey Brad,
It’s a long explanation, so I appended my answer to the post above. The short version is: I took the XmlElement route because I could change fewer lines of code. I didn’t have to create a new WebContentTypeMapper-derived class and figure out where to plug it in.
What do you think? An ugly hack?
Dean