在 .NET MVC 4 (Web API) 中,如何拦截对控制器的请求并更改其 Content-Type?
Posted
技术标签:
【中文标题】在 .NET MVC 4 (Web API) 中,如何拦截对控制器的请求并更改其 Content-Type?【英文标题】:In .NET MVC 4 (Web API), how do I intercept a request for a controller and change it's Content-Type? 【发布时间】:2012-12-31 05:12:48 【问题描述】:感谢收看!
背景
我正在为一家公司编写一个 API 层,供不同的应用程序和外部消费者使用。
在消费端,大部分消费者会使用jQuery$.post()
通过ajax调用服务;然而,Internet Explorer 让我们的生活更具挑战性(当然!)。对于 IE,我必须使用 XDomainRequest
对象,因为 IE 不会运行 jQuery $.post()
,而且如果我使用 IE 的 XMLHttpRequest()
,我会收到一条不可接受的安全消息(再次——当然!):
否则,XMLHttpRequest()
工作正常。
我正在使用 C#、.NET MVC 4 (WebApi)
问题
问题在于XDomainRequest
不允许您设置Content-Type
标头,并且始终默认为text-plain
,这是MVC 4 WebApi 控制器将不接受的(再一次——当然!!)。
问题
如何拦截对我的控制器的请求,检测text-plain
内容类型的存在并将它们即时更改为text-json
内容类型?
提前致谢!
【问题讨论】:
"因为 IE 不会运行 jQuery $.post()" 你确定吗? 我使用的是 IE 8,但它似乎没有这样做,可能是因为它是跨域的。让我再检查一下。 . . 看了一圈后,尝试在帖子 url 的末尾添加一个缓存破坏参数:例如$.post("my/url?d=" + new Date().getMilliseconds().....) @BFree--是的。在 IE8 中,我可以在$.post()
上设置一个断点,它会被命中,但回调函数永远不会执行。就好像 IE 只是跨过.post()
。相同的.post()
代码在其他浏览器中运行良好。
@Bfree--好的,尝试了 cacheBuster,但遗憾的是没有帮助。
【参考方案1】:
两天后,翻阅文档并阅读此线程,我已经能够完成这项工作。所以如果我对解决方案的描述很差,请原谅我;这是我第一次回答这些类型的线程之一。因为我花了很长时间才找到问题,所以我认为值得拯救一些人,以免陷入同样的问题。
我的帮助来源来自byterot的上述链接。
我做的第一件事是创建一个DelegatingHandler。因此,在我的帮助文件夹或每个您想要创建一个类的地方,并按您的意愿命名。 这是我的:
public class ContentTypeHandler : DelegatingHandler
/** Check that this is an IE browser. */
if ((request.Headers.UserAgent.ToString().IndexOf("MSIE", System.StringComparison.Ordinal) > -1))
MediaTypeHeaderValue contentTypeValue;
if (MediaTypeHeaderValue.TryParse("application/json", out contentTypeValue))
request.Content.Headers.ContentType = contentTypeValue;
request.Content.Headers.ContentType.CharSet = "utf-8";
/** Return request to flow. */
return base.SendAsync(request, cancellationToken)
.ContinueWith(task =>
// work on the response
var response = task.Result;
return response;
);
最后认为你必须做的是在你的Application_Start()
中调用Global.asax.cs
文件中的处理程序:
GlobalConfiguration.Configuration.MessageHandlers.Add(new ContentTypeHandler());
这就是我所做的一切,它奏效了。祝你好运,我希望这对某人有所帮助。
【讨论】:
【参考方案2】:在 HTTP 堆栈中修改请求没有问题。它可以通过在到达控制器之前编写和注册您的自定义DelegatingHandler
来完成。委托处理程序可以在游戏的早期处理此问题,因此您的请求将以您想要的形式到达控制器。它也可以是特定于路由的处理程序。
http://msdn.microsoft.com/en-us/library/system.net.http.delegatinghandler.aspx
您是否尝试过使用 $.ajax 而不是 $.post ?
【讨论】:
是的,我已经尝试过各种 jQuery 帖子、ajacx 等。似乎 IE 根本不允许通过 jquery 进行跨域 ajax 帖子。我很欣赏在委派处理程序上指向 msdn 文档的链接,但如果您有示例代码,那就太好了。 这是很好的委托处理程序源代码byterot.blogspot.com/search?q=delegatinghandler以上是关于在 .NET MVC 4 (Web API) 中,如何拦截对控制器的请求并更改其 Content-Type?的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET MVC 4,Web API - 404 未找到
正确处理 ASP.net MVC 4 Web Api 路由中的嵌套资源
ASP.Net MVC 4 Web API 控制器不适用于 Unity.WebApi
在 .NET MVC 4 (Web API) 中,如何拦截对控制器的请求并更改其 Content-Type?
无法使用 ASP.NET (MVC 4) Web API OData Prerelease 加载文件或程序集 System.Net.Http,版本 = 4.0.0.0