jQuery中是否有类似于Request.IsMvcAjaxRequest()的方法?

8
我更喜欢在我的ASP.NET MVC应用程序中使用jQuery而不是Microsoft Ajax库。我一直在向我的操作添加一个名为“mode”的参数,然后在我的ajax调用中设置它。如果提供了它,我会返回一个JsonViewResult。如果没有提供,我假设它是标准的Http post,然后返回一个ViewResult。
当使用jQuery时,我想能够在我的控制器中使用类似于IsMvcAjaxRequest的东西,这样我就可以消除我的Actions中的额外参数。
是否有任何东西可以在我的控制器中提供这种功能或者有一些简单的方法来完成它?我不想写太多代码,因为添加一个单独的参数是有效的,但并不理想。

对于任何感到困惑的人,IsMvcAjaxRequest现在已经更名(自RC1起)为IsAjaxRequest,这样就可以与其他Ajax库兼容了。请参见我下面的帖子。 - Simon_Weaver
4个回答

12

以下是MVC RC1的发布说明 - 2009年1月摘录

IsMvcAjaxRequest已更名为IsAjaxRequest

IsMvcAjaxRequest方法已更名为IsAjaxRequest。作为此更改的一部分,IsAjaxRequest方法已更新以识别X-Requested-With HTTP头。这是由各种JavaScript库发送的众所周知的标头,例如Prototype.js、jQuery和Dojo。

ASP.NET AJAX助手已更新为在请求中发送此标头。但是,它们继续将其发送到表单提交的正文中,以解决防火墙剥离未知标头的问题。

换句话说,它被特意重命名以更与其他库兼容。

另外,对于那些没有阅读完整的发布说明但仍在使用以前版本(甚至是Beta)的人们,我强烈建议您仔细阅读它们。这将为您节省时间,并且很可能会让您对一些新功能感到兴奋。里面有很多新东西,相当惊人。

重要提示:如果从Beta升级到RC1,则需要确保升级MicrosoftAjax.MVC(不是确切的名称)的.js文件-否则此方法将不起作用。它未在发布说明中列为升级所需的任务,因此不要忘记进行更新。


谢谢Simon,希望Andrew Van Slaars会给你采纳的答案。 - Eric Schoonover
此外,我已将我的帖子更改为社区 Wiki,以防其他人想要更新“已接受的答案”。 - Eric Schoonover
谢谢。我相信我的答案也会有一天过时 :) 当你写下你的答案时,我甚至还没有听说过ASP.NET MVC :) - Simon_Weaver

4
请参考下面的Simon答案。目前ASP.NET MVC的最新版本不再需要我在这里描述的方法。
目前IsMvcAjaxRequest扩展方法的工作方式是检查Request["__MVCASYNCPOST"] == "true",并且仅在方法为HTTP POST请求时起作用。
如果您通过jQuery进行HTTP POST请求,可以动态插入__MVCASYNCPOST值到您的请求中,然后您就可以利用IsMvcAjaxRequest扩展方法。
这里提供 IsMvcAjaxRequest扩展方法源代码链接方便您查看。
或者,您可以创建一个名为IsjQueryAjaxRequestIsMvcAjaxRequest扩展方法副本,它检查Request["__JQUERYASYNCPOST"] == "true",并且您可以动态地将该值插入到HTTP POST中。 更新 我决定尝试一下,这是我想出来的东西。
扩展方法。
public static class HttpRequestBaseExtensions
{
    public static bool IsjQueryAjaxRequest(this HttpRequestBase request)
    {
        if (request == null)
            throw new ArgumentNullException("request");

        return request["__JQUERYASYNCPOST"] == "true";
    }
}

通过一个动作检查一个方法是否为jQuery $.ajax()请求:

if (Request.IsjQueryAjaxRequest())
    //some code here

JavaScript

$('form input[type=submit]').click(function(evt) {
    //intercept submit button and use AJAX instead
    evt.preventDefault();

    $.ajax(
        {
            type: "POST",
            url: "<%= Url.Action("Create") %>",
            dataType: "json",
            data: { "__JQUERYASYNCPOST": "true" },
            success: function(data) {alert(':)');},
            error: function(res, textStatus, errorThrown) {alert(':(');}
        }
    );
});

那我在使用“$.post”时,是否像其他参数一样将__JQUERYASYNCPOST作为我的POST数据的参数传递?如果是这样,那么这将给我提供相同的基本设置,而无需额外的参数,这将是完美的。 - Andrew Van Slaars
是的,在$.post()的数据参数中传递值。我建议先使用__MVCASYNCPOST进行测试,以确保它可以与现有的扩展方法一起使用。如果可以,那么您可以实现自己的扩展方法并将其更改为__JQUERYASYNCPOST。 - Eric Schoonover
再次感谢,我刚刚在我正在开发的项目中实现了这段代码。如果我在编写代码之前再看一遍这里,我就可以直接复制粘贴了 :) - Andrew Van Slaars
请注意,RC1中有重要更改,请查看我的答案。 - Simon_Weaver

3

为什么不直接检查大多数JavaScript库(如jQuery)自动发送的“X-Requested-With”HTTP标头呢?

当发送GET或POST请求时,它的值为“XMLHttpRequest”。

为了测试它,您只需要在操作中检查“Request.Headers” NameValueCollection,即:

if (Request.Headers["X-Requested-With"] == "XMLHttpRequest")
    return Json(...);
else
    return View();

这样,您就可以轻松区分普通的浏览器请求和Ajax请求。

好主意。我将避免更改我的答案,以便您可以获得尽可能多的声誉 :) - Eric Schoonover
我之前并没有意识到请求头中有“requested-with”这个字段。我会去查一下并尝试一下,也许我会更新扩展方法来检查它。你有什么想法为什么微软一开始没有这样做呢? - Andrew Van Slaars
实际上,据我所知,关于这个话题缺乏标准化。所有的库都以不同的方式构建它们的头文件(有些指定了库的版本),但幸运的是,大多数都采用了“X-Requested-With”,我无法理解为什么微软没有采用。 - Franck
@sork 好的,自从 RC1 以后他们现在认识到了。 - Simon_Weaver

0

好的,我已经更进一步地修改了我的jQuery文件,将附加参数加载到POST数据中,这样我就不必在每次调用POST时重复使用“__JQUERYASYNCPOST:true”了。对于任何有兴趣的人,这是我新的$.post定义:

post: function(url, data, callback, type) {
            var postIdentifier = {};
            if (jQuery.isFunction(data)) {
                callback = data;
                data = {};
            }
            else {
                postIdentifier = { __JQUERYASYNCPOST: true };
                jQuery.extend(data, postIdentifier);
            }

            return jQuery.ajax({
                type: "POST",
                url: url,
                data: data,
                success: callback,
                dataType: type
            });
        }

我添加了“postIdentifier”变量以及对jQuery.extend的调用。现在,在不需要添加任何特殊内容到我的页面级别的jQuery代码的情况下,spoon16回答中解释的Helper可以正常工作。


很好...这是SO上最完整的QA之一 :) - Eric Schoonover
如果你扩展了'ajax()'会怎样?这样做不是更好吗,因为所有其他方法(如'post()')都只是通过'ajax'调用的。 - Eric Schoonover
我本可以扩展ajax,但我的主要关注点是post。通常,如果它是仅限于ajax的功能,例如自动完成查找或类似功能,没有ajax就不可用,那么我只使用get来进行Ajax,因此对于这些事情,我无论如何都会使用JsonResult。 - Andrew Van Slaars

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接