【问题标题】:Cannot accept XDomainRequest POST to WebAPI无法接受 XDomainRequest POST 到 WebAPI
【发布时间】:2013-11-16 14:26:02
【问题描述】:

我有一个控制器类,我可以在 API 上发起 Get 调用,但是当我尝试 POST 命令时,我得到 HTTP/1.1 415 Unsupported Media Type

有什么地方我必须允许 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)
    {
    }
}

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

}

【问题讨论】:

  • 你到底是什么以及如何发布?
  • 您可能将接受标头设置为您的应用程序不支持的类型。请出示您的邮政编码。
  • 我已经添加了 javascript 邮政编码(一开始会很有用:)
  • 我正在发布测试数据,例如:value=Test
  • 我希望这会显示在方法中:public string Post([FromBody]string value)

标签: json post asp.net-web-api xdomainrequest


【解决方案1】:

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

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

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

GlobalConfiguration.Configuration.Formatters.Add(new OctetStreamMediaFormatter());

在您的ApiController 中装饰相应的方法:

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

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

config.EnableCors();

现在应该可以使用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);

}

【讨论】:

  • +10gazillion 点,我一直在阅读并尝试 intawebz 上的所有选项,以尝试让 IE9 CORS 与 json 发布数据一起使用,你太棒了!
  • +11gazillion 点。我认为 XDomainRequest 的默认内容类型是 text/plain !!!我已经创建了一个 TextPlainMediaFormatter 并且什么都没有。现在可以在 webapi 2 中使用。非常感谢!
【解决方案2】:

好吧,value=Test 不是有效的 json。您可以发送 json 格式,因为您已将 application/json 设置为 content-type 标头请求属性,例如:

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

在服务器端,尝试创建一个DTO对象:

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

然后加入post 方法:

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

【讨论】:

  • 谢谢,效果很好。我唯一的问题是迎合 IE8/9,这就是我使用 XDomainRequest 处理跨源问题的原因。我知道其中存在一个错误,即 XDomainRequest 无法处理类型 application/json。我可以测试 text/plain 并转换它吗?目前,如果从 XDomainRequest 发布但在 REST 测试客户端上运行良好,我会得到 415
  • 我认为这可能会做到这一点:myadventuresincoding.wordpress.com/2012/06/19/… ?
  • 致任何阅读本文的人。我看不到如何通过 POST 将 JSON 发送到 webapi,因为您无法更改标头或内容类型。我在这上面花了 2 天的时间,不得不得出结论,在 IE
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-20
  • 1970-01-01
相关资源
最近更新 更多