使用ASP.NET MVC和JQuery表单插件/文件上载检测IsAjaxRequest()

我正在使用JQuery Form插件在ASP.NET MVC应用程序上执行文件上载。 我已经了解到,由于iframe用于文件上传(而不是XMLHttpRequest,这是不可能的),因此IsAjaxRequest的服务器端检查失败。

我已经看到了一些与此问题相关的post,但没有遇到任何解决此问题的好方法。 与我的其他应用程序一样,我希望能够同时支持启用JavaScript和禁用JavaScript的方案,这就是我想检测请求是否为ajax的原因。

我意识到使用的iframe方法在技术上并不是ajax,但我试图模仿ajax效果。

欢迎大家提出意见。

我刚刚意识到我完全没有回答这个问题,所以我在这里添加到顶部,并在下面留下我的旧答案:

问题是当通过iFrame发布文件时,未设置“X-Requested-With”标头,并且您无法在Javascript中为普通表单POST设置特定请求标头。 您将不得不求助于其他技巧,例如使用包含值的POST发送隐藏字段,然后更改或覆盖“IsAjaxRequest”扩展方法以检查此情况。 如何覆盖现有的扩展方法?

可能最好的选择可能是使用不同的名称包含您自己的扩展方法,基于默认的MVC扩展方法代码以及检测您的iFrame上传POST的更改,然后在您希望需要它的任何地方使用您的扩展方法。


jQuery实际上默认将’X-Requested-With’标头设置为’XMLHttpRequest’。 只要您小心地通过jQuery执行所有AJAX调用,它就非常有用。

根据您的需要,可以在动作filter中轻松设置检测以在需要时使用它,甚至可以将其构建到控制器类中,如下所示:

[jQueryPartial] public abstract class MyController : Controller { public bool IsAjaxRequest { get; set; } } 

ActionFilterAttribute:

 public class jQueryPartial : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext filterContext) { // Verify if a XMLHttpRequest is fired. // This can be done by checking the X-Requested-With // HTTP header. MyController myController = filterContext.Controller as MyController; if (myController != null) { if (filterContext.HttpContext.Request.Headers["X-Requested-With"] != null && filterContext.HttpContext.Request.Headers["X-Requested-With"] == "XMLHttpRequest") { myController.IsAjaxRequest = true; } else { myController.IsAjaxRequest = false; } } } } 

并使用实现:

 public class SomeController : MyController { public ActionResult Index() { if (IsAjaxRequest) DoThis(); else DoThat(); return View(); } } 

您需要为IsAjaxRequest方法设置“X-Requested-With”标头以返回true。 这是你在jquery中的表现。

 $(document).ready(function() { jQuery.ajaxSetup({ beforeSend: function (xhr) { xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); return xhr; } }); }); 

从ASP.NET MVC 2(及以后)开始, Request上有一个扩展方法。

 if (Request.IsAjaxRequest()) { // was an ajax request } 

在控制器方法上使用诸如.load()之类的jQuery方法将导致Request.IsAjaxRequest()返回true。

我偶然发现了这个问题,后来找到了更好的解决方案,所以这里(对于从谷歌到这里的所有人):

jQuery表单插件有两个选项可能在这种情况下有所帮助。

  1. 如果你正在使用post请求,它似乎总是使用iframe,所以如果你不需要文件上传,在表格选项中设置iframe = false在我的情况下有帮助。

  2. 如果你需要iframe用于fileuploads,你可以使用选项的data属性来欺骗

    IsAjaxRequest() setting : data: { "X-Requested-With": "XMLHttpRequest" }

包含两个选项的完整脚本如下所示:

 $('#someform').ajaxForm( { dataType: 'json', success: onSuccess, error: onError, iframe: false data: { "X-Requested-With": "XMLHttpRequest" } } );