Question

I have a controller class and I can initiate a Get call on the API but when I try a POST command I get HTTP/1.1 415 Unsupported Media Type

Is there somewhere that I have to allow POST? I placed [HttpPost] in front of the method but no luck.

public class initController : ApiController
{
    // GET api/<controller>
    public IEnumerable<string> Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET api/<controller>/5
    public string Get(int id)
    {
        return "value";
    }

    // POST api/<controller>
    [HttpPost]
    public string Post([FromBody]string value)
    {
        oTree myT = new oTree();
        myT.build(0);
        myT.entity.question = value;
        return JsonConvert.SerializeObject(myT);
    }

    // PUT api/<controller>/5
    public void Put(int id, [FromBody]string value)
    {
    }

    // DELETE api/<controller>/5
    public void Delete(int id)
    {
    }
}

Javscript post code:

function gpRequest(service, verb, oData, callback) {
if (bool_cantransmit) {
    bool_cantransmit = false;
    var xdr;
    var url = base_service_url + service + "/";
    if (window.XDomainRequest) // Check whether the browser supports XDR. 
    {
        xdr = new XDomainRequest(); // Create a new XDR object.
        if (xdr) {
            xdr.onerror = errorHandler;
            xdr.onload = callback;
            xdr.contentType = "application/json";
            xdr.open(verb, url);
            xdr.send(oData);
        }
    } else {
        var xhr = new XMLHttpRequest();
        xhr.onerror = errorHandler;
        xhr.onload = callback;

        xhr.open(verb, url, true);
        xhr.send(oData);
    }
}

}

Was it helpful?

Solution 2

Well, value=Test is not a valid json. You could send a json format since you have setted application/json to the content-type header request property, for sample:

gpRequest(service, 'POST', "{ Value: 'Test' }", callback);

In the server side, try to create a DTO object:

public class MessageDTO
{
   public string Value { get; set; }
}

And get in on the post method:

[HttpPost]
public string Post([FromBody]MessageDTO message)
{
    oTree myT = new oTree();
    myT.build(0);
    myT.entity.question = message.Value;
    return JsonConvert.SerializeObject(myT);
}

OTHER TIPS

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);

}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top