Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc 带有CORS和IE9的ASP Web API POST请求(XDomainRequest对象)_Asp.net Mvc_Jquery_Asp.net Web Api_Cors - Fatal编程技术网

Asp.net mvc 带有CORS和IE9的ASP Web API POST请求(XDomainRequest对象)

Asp.net mvc 带有CORS和IE9的ASP Web API POST请求(XDomainRequest对象),asp.net-mvc,jquery,asp.net-web-api,cors,Asp.net Mvc,Jquery,Asp.net Web Api,Cors,为了让jquery.ajax与ie9协同工作,我在这里简直疯了。所以我有一个实现CORS的ASP Web API 2 Rest API。来自所有浏览器的CORS请求都有效。IE9没有工作,因为它使用XDomainRequest。通过为IE9定制ajaxTransport的实现,我成功地实现了它 现在,GET请求似乎工作正常。但是当我从IE9发出post请求时,我得到一个HTTP错误415-未支持的媒体类型 我已经将内容类型设置为:“application/json”,还尝试了“applicati

为了让jquery.ajax与ie9协同工作,我在这里简直疯了。所以我有一个实现CORS的ASP Web API 2 Rest API。来自所有浏览器的CORS请求都有效。IE9没有工作,因为它使用XDomainRequest。通过为IE9定制ajaxTransport的实现,我成功地实现了它

现在,GET请求似乎工作正常。但是当我从IE9发出post请求时,我得到一个HTTP错误415-未支持的媒体类型

我已经将内容类型设置为:“application/json”,还尝试了“application/x-www-form-urlencoded”,但据我所知,XDomainRequest不支持自定义标题的所有内容?有人知道是否需要在WebAPI上设置特定的内容,或者我需要调整请求吗

我的请求如下所示:

                        $.ajax({
                        url: hostname + "/api/DDC/Book",
                        type: "POST",

                        contentType: "application/json",
                        data: {
                            DealID: function () {
                                return viewModel.get("DealID");
                            },
                            LocationID: function () {
                                return viewModel.get("LocationID");
                            },
                            Time: function () {
                                return viewModel.get("selectedDateTime.Time");
                            }

                        }
                    })
在服务器上,我有:

[HttpPost("DDC/Book")]
    [EnableCors(origins: "*", headers: "*", methods: "POST, GET, OPTIONS, PUT, DELETE")]
    public dynamic Post(BookModel model)
    {
       .........
当我在IE调试器中分析失败的请求时,以下是发送的请求头:

Key Value
Request POST //api/DDC/Book HTTP/1.1
Accept  */*
Origin  http://myurl.com
Accept-Language hr-HR
Accept-Encoding gzip, deflate
User-Agent  Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
Host    www.somehost.com
Content-Length  55
DNT 1
Connection  Keep-Alive
Cache-Control   no-cache
我真的失去了所有的希望,IE让我发疯了(该死的微软:D),所以任何帮助或建议都是非常感谢的

编辑:从更多的研究中,我发现WebAPI需要一个内容类型才能工作,而XDomainRequest没有发送一个。因此,我看到的唯一解决方案是在没有设置任何内容的情况下,过于调整我的webapi而没有默认的内容类型。但我还不知道该怎么做


EDIT2:通过转换我所有的帖子,暂时破解了我的问题,我不知道这有多聪明,但我现在看不出有什么更大的问题,所以在我解决问题之前,我会一直这么做,只是为了确认你已经在几次更新中编辑了你的问题:是的,XDomainRequest在请求中不包含内容类型标头。正如您现在可能知道的,您不能通过此传输设置任何头

对于大多数服务器端框架来说,缺少内容类型的问题尤其严重,因为这意味着它们将无法自动解析响应的内容。在没有内容类型头的情况下,RFC2616表示主体被假定为应用程序/八位字节流,这可能不是您在本例中想要的。因此,在本例中,您需要通过硬编码关联请求的预期内容类型来“手动”解析请求主体服务器端


我强烈建议你不要把所有的帖子都转换成GET。根据RFC 2616,GET请求应该是“安全的”。通过简单地将所有帖子重命名为GET,您就不再遵循GET请求的定义和接受的语义。换句话说,不要这样做。

我自己设法解决了这个问题。正如Ray Nicholus指出的,当没有内容类型时,ASP Web API默认为“应用程序/八位字节流”内容类型。我需要一个默认值“application/x-www-form-urlencoded”

我通过编写自己的简单消息处理程序来实现这一点,该处理程序检查传入请求的“内容类型”,如果不存在任何内容,则添加一个“application/x-www-form-urlencoded”消息处理程序

代码如下:

public class DefaultContentTypeMessageHandler : DelegatingHandler
{
    protected async override Task<HttpResponseMessage> SendAsync(
HttpRequestMessage request, CancellationToken cancellationToken)
    {
        if (request.Content.Headers.ContentType == null)
            request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");


        var response = await base.SendAsync(request, cancellationToken);


        return response;
    }

}

Dennis在上面的回答中使用了async,这仅在.NET4.5中可用。对于.NET 4或更低版本,请改用以下委托处理程序:

 public class DefaultContentTypeMessageHandler : DelegatingHandler
 {
      protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
      {
          if (request.Method == HttpMethod.Post && request.Content.Headers.ContentType == null)
          {
              request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
          }
          return base.SendAsync(request, cancellationToken);
      }
 }

Thx用于响应。是的,我知道关于GET,并且非常同意,在我修复它之前,它只是一个临时的黑客操作,它还不是生产代码。对于将要更改的生产阶段。它在一个小部件API中只有2篇文章。应用程序/八位字节流信息是我不知道的,也是有用的。换句话说,如果不清楚,您需要服务器代码来了解请求正文的格式,以便它可以手动解析这些请求,因为XDR不允许在请求中包含内容类型。这几乎就是我最后要做的。对于那些乍一看不懂的人,DelegatingHandler允许您在请求/响应对象真正进入WebAPI框架内部之前修改它们。框架中的任何其他内容都不允许您在模型绑定之前修改传入请求,而无需实际编写自定义模型绑定(eugh)。因此,在这里,您可以嗅出一个空的内容类型(XDomainRequest规范中的缺陷保证了这一点),将其更新为xml或json,这样您就能够正确解析传入的请求了!,这个答案让我很高兴。我在IE8/9上也遇到了同样的问题,效果非常好。
 public class DefaultContentTypeMessageHandler : DelegatingHandler
 {
      protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
      {
          if (request.Method == HttpMethod.Post && request.Content.Headers.ContentType == null)
          {
              request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/x-www-form-urlencoded");
          }
          return base.SendAsync(request, cancellationToken);
      }
 }
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;