Asp.net mvc 带有CORS和IE9的ASP Web API POST请求(XDomainRequest对象)
为了让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上设置特定的内容,或者我需要调整请求吗 我的请求如下所示: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
$.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;