After experiencing similar problems I decided to write this down for future reference.
The problem with XDomainRequest
is that it doesn't add a Content-Type
header.
This means that the Content-Type
will default to application/octet-stream
for which there are no default MediaTypeFormatters
. This causes the API to reject the request with 415 Unsupported Media Type
.
One possible workaround is to assume that application/octet-stream
is application/json
.
Create a new OctetStreamMediaFormatter
that derives from JsonMediaTypeFormatter
but also accepts application/octet-stream
:
public class OctetStreamMediaFormatter : JsonMediaTypeFormatter
{
public OctetStreamMediaFormatter()
{
SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
}
}
Add the new formatter to your configuration (e.g in Global.asax.cs
)
GlobalConfiguration.Configuration.Formatters.Add(new OctetStreamMediaFormatter());
In your ApiController
decorate the appropriate method:
[HttpPost]
[EnableCors(origins: "*", headers: "*", methods: "POST")]
public HttpResponseMessage ExampleAction(ExampleModel model)
{
if (ModelState.IsValid)
{
...
}
...
}
[EnableCors(...)]
adds the required Access-Control-Allow-Origin
header to the response. Enable CORS (e.g. in WebApiConfig.cs
):
config.EnableCors();
It should now be possible to send and receive data using XDomainRequest
.
function xdr(json) {
if (!window.XDomainRequest) {
console.log("Sorry, XDomainRequest not supported");
return;
}
var xdr = new XDomainRequest();
xdr.onerror = function () {
console.log("Sorry, XDomainRequest.onerror()");
};
xdr.onload = function () {
console.log(xdr.responseText);
};
xdr.open("POST", "ExampleApiController/ExampleAction");
xdr.send(json);
}