Reputation: 6649
I have a WCF REST service with an operation like this:
[OperationContract]
[WebInvoke(UriTemplate = "/User", BodyStyle = WebMessageBodyStyle.Bare, Method = "POST", RequestFormat = WebMessageFormat.Json)]
void User(User user);
When i call this from Fiddler, it works fine if i specify the Content-Type="application/json" like so:
Content-Type: application/json
Host: localhost:58150
Content-Length: 172
Expect: 100-continue
But if i exclude The Content-Type then i get an error 400 since it tries to process the request body as XML. This is very annoying, you would REALLY THINK that setting RequestFormat = WebMessageFormat.Json would make it so that i DO NOT have to specify the Content-Type but that is not the case. As a matter of fact if i drop 'RequestFormat' nothing changes. I have also tried 'wrapped' for the WebMessageBodyStyle but then the DTO comes through null.
To Clarify, this happens if i use XML in the body of the post as well (and omit the Content-Type)... so what I really want to accomplish is:
How do I make my WCF Rest methods not require Content-Type when using WebInvoke (I would expect WCF to figure it out automatically)
This is driving me crazy PLEASE help.
Upvotes: 1
Views: 1366
Reputation: 121
You need to add a WebContentTypeMapper on your WebHttpBinding. In that you can tell the WCF runtime what WebContentFormat the supplied (or assumed) content type mime value supplied. Generally when a POST is received without the content-type header, this will be "application/x-www-form-urlencode" (multipart/form-data or text/plain can happen as well so be aware). Simply tell WCF that this is Json Or Xml (or whatever you need) and it will just work (your millage may vary).
public class YourContentTypeMapper : WebContentTypeMapper
{
public override WebContentFormat GetMessageFormatForContentType(string contentType)
{
if (contentType == "application/x-www-form-urlencode")
{
return WebContentFormat.Json; // assuming this is wanted
}
else
{
return WebContentFormat.Default;
}
}
}
Simply set the ContentTypeMapper to on the WebHttpBinding to an instance of your class (this can be done in config file as well on your binding with the contentTypeMapper attribute)
var binding = new WebHttpBinding();
binding.ContentTypeMapper = new YourContentTypeMapper();
More information => https://msdn.microsoft.com/en-us/library/bb943479(v=vs.110).aspx
Upvotes: 1
Reputation: 475
Have you tried to set automaticFormatSelectionEnabled
on your endpoint behaviour to true?
Take into consieration that this attribute is specific to NET 4.0, i remember using it to format response messages based on Accept header of http.
I haven't tried to reproduce your scenario, but reading this official documentation link it states the following:
If the request message contains an Accept header the Windows Communication Foundation (WCF) infrastructure searches for a type that it supports. If the Accept header specifies priorities for its media types, they are honored. If no suitable format is found in the Accept header, the content-type of the request message is used. If no suitable content-type is specified, the default format setting for the operation is used.
Here is the example from msdn of how automaticFormatSelectionEnabled is set.
<behaviors>
<endpointBehaviors>
<behavior>
<webHttp automaticFormatSelectionEnabled="true" />
</behavior>
</endpointBehaviors>
</behaviors>
Upvotes: 0