无法接受XDomainRequest POST到WebAPI

spa*_*out 2 post json xdomainrequest asp.net-web-api

我有一个控制器类,我可以在API上启动Get调用但是当我尝试POST命令时,我得到HTTP/1.1 415不支持的媒体类型

有什么地方我必须允许POST吗?我把[HttpPost]放在方法前面,但没有运气.

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)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

Javscript邮政编码:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

}

Lin*_*nus 6

遇到类似问题后,我决定将其写下来以备将来参考.

问题XDomainRequest是它没有添加Content-Type标题.这意味着Content-Type将默认application/octet-stream为没有默认值MediaTypeFormatters.这会导致API拒绝请求415 Unsupported Media Type.

一种可能的解决方法是假设application/octet-streamapplication/json.

创建一个OctetStreamMediaFormatter派生自的新东西,JsonMediaTypeFormatter但也接受application/octet-stream:

public class OctetStreamMediaFormatter : JsonMediaTypeFormatter
{
    public OctetStreamMediaFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("application/octet-stream"));
    }
}
Run Code Online (Sandbox Code Playgroud)

将新格式化程序添加到您的配置中(例如Global.asax.cs)

GlobalConfiguration.Configuration.Formatters.Add(new OctetStreamMediaFormatter());
Run Code Online (Sandbox Code Playgroud)

在你的ApiController装饰中适当的方法:

[HttpPost]
[EnableCors(origins: "*", headers: "*", methods: "POST")]
public HttpResponseMessage ExampleAction(ExampleModel model)
{
    if (ModelState.IsValid)
    {
        ...
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

[EnableCors(...)]将所需的Access-Control-Allow-Origin标头添加到响应中.启用CORS(例如WebApiConfig.cs):

config.EnableCors();
Run Code Online (Sandbox Code Playgroud)

现在应该可以使用发送和接收数据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);

}
Run Code Online (Sandbox Code Playgroud)