[转]深入ASP.NET MVC之九:Ajax支持

本文转自:http://www.cnblogs.com/yinzixin/archive/2012/12/22/2824384.html

目前前端页面和服务端进行Ajax交互大多采用的都是jQuery, ASP.NET MVC提供了一些方法使得这个过程变得更加容易。常见的Ajax应用场景有两种,一个是点击一个链接,然后局部加载一些内容,可以是html片段,也可能是json数据,然后通过前端js处理之后显示;另一个是异步提交表单。这些帮助方法都是位于AjaxExtensions种的扩展方法。先看第一类场景,这是通过ActionLink来生成一个点击之后可以异步加载数据的链接。

1. Ajax Action Link

先看下如何使用这些方法,首先保证页面加载了依赖的js库:

<script src="@Url.Content("~/Scripts/jquery-1.6.2.min.js")" type="text/javascript"></script>
    <script src="@Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>

假如有如下的Controller:

public class AjaxController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public string Result(string name)
        {
            System.Threading.Thread.Sleep(2000);
            return "This is " + name;
        }
    }

View文件如下:

@{
    ViewBag.Title = "Index";
    string[] data = new string[] { "Jack", "Tom", "Kathy" };
}
<style type="text/css">
    a {
        margin:10px;
    }
    #loading {
        display:none;
        color:red;
    }
</style>
<div>
    @foreach (var n in data)
    {
        @Ajax.ActionLink(n, "Result", new { name = n }, new AjaxOptions{
             UpdateTargetId = "tabledata",
             LoadingElementId = "loading"
        });
    }
</div>
<div id="loading">
    Loading Data...
</div>
<div id="tabledata">

</div>

这样的效果便是点击超链接,从Result这个action方法就会被插入到id为tabledata的div中,在加载的过程中,id为loading的div会显示。应该说,这是一种非常常见的操作场景。在asp.net mvc的帮助下,我们不需要多写任何js代码就可以实现这一效果。下面来看下这是如何实现的。先看ActionLink生成了什么html代码:

<a data-ajax="true" data-ajax-loading="#loading" data-ajax-mode="replace" data-ajax-update="#tabledata" href="/Ajax/Result?name=Jack">Jack</a>

ActionLink的源代码没有太多复杂的地方,只是按规则生成这个标签而已,唯一复杂的地方是href的生成,但这个不是本文讨论的重点,这和routing模块关系更加紧密一些,有机会另文分析。真正实现功能的地方都是在jquery.unobtrusive-ajax.js这个文件中,这是一个jquery的插件,首先在插件被加载的时候,执行了如下代码:

    $("a[data-ajax=true]").live("click", function (evt) {
        evt.preventDefault();
        asyncRequest(this, {
            url: this.href,
            type: "GET",
            data: []
        });
    });

利用jQuery的live方法设置了click事件设置为asyncRequest方法:

function asyncRequest(element, options) {
        var confirm, loading, method, duration;

        confirm = element.getAttribute("data-ajax-confirm");
        if (confirm && !window.confirm(confirm)) {
            return;
        }

        loading = $(element.getAttribute("data-ajax-loading"));
        duration = element.getAttribute("data-ajax-loading-duration") || 0;

        $.extend(options, {
            type: element.getAttribute("data-ajax-method") || undefined,
            url: element.getAttribute("data-ajax-url") || undefined,
            beforeSend: function (xhr) {
                var result;
                asyncOnBeforeSend(xhr, method);
                result = getFunction(element.getAttribute("data-ajax-begin"), ["xhr"]).apply(this, arguments);
                if (result !== false) {
                    loading.show(duration);
                }
                return result;
            },
            complete: function () {
                loading.hide(duration);
                getFunction(element.getAttribute("data-ajax-complete"), ["xhr", "status"]).apply(this, arguments);
            },
            success: function (data, status, xhr) {
                asyncOnSuccess(element, data, xhr.getResponseHeader("Content-Type") || "text/html");
                getFunction(element.getAttribute("data-ajax-success"), ["data", "status", "xhr"]).apply(this, arguments);
            },
            error: getFunction(element.getAttribute("data-ajax-failure"), ["xhr", "status", "error"])
        });

        options.data.push({ name: "X-Requested-With", value: "XMLHttpRequest" });

        method = options.type.toUpperCase();
        if (!isMethodProxySafe(method)) {
            options.type = "POST";
            options.data.push({ name: "X-HTTP-Method-Override", value: method });
        }

        $.ajax(options);
    }

这个方法还是比较清晰的。首先根据options确定是否弹出一个确认框,然后是设置加载等待的元素和显示时间。接下来就是给options添加几个回调函数,这个options其实最终就是给jquery的ajax方法的参数。下面简单看下在设置回调函数的时候主要调用的getFunction方法:

function getFunction(code, argNames) {
        var fn = window, parts = (code || "").split(".");
        while (fn && parts.length) {
            fn = fn[parts.shift()];
        }
        if (typeof (fn) === "function") {
            return fn;
        }
        argNames.push(code);
        return Function.constructor.apply(null, argNames);
    }

这个方法接受两个参数,第一个code,就是在AjaxOptions中OnXXX属性上设置的值,第二个是argNames,表示的是这个回调函数的参数名字。首先它是从window对象开始查找是否有名字为code的函数,如果有,就直接返回那个函数;否则,code就是代码而不是函数名称,利用Function的构造函数创建一个新的函数。因此,OnBegin的值用如下的两种形式都是可以的:

@Ajax.ActionLink(n, "Result", new { name = n }, new AjaxOptions{
             UpdateTargetId = "tabledata",
             LoadingElementId = "loading",OnBegin="  alert(\"on begin\");return false;"
        });

或者

<script type="text/javascript">
            function Begin() {
                alert("on begin");
            }
        </script>
        @Ajax.ActionLink(n, "Result", new { name = n }, new AjaxOptions
   {
       UpdateTargetId = "tabledata",
       LoadingElementId = "loading",
       OnBegin = " Begin"
   });

用第一种方式仍然可以使用参数。参数的名字见源代码。这里的JavaScript技巧值得学习下。ActionLink的原理就是这样,把原来使用jquery要做的一些准备工作包装的更加简单。

等到调用结束之后,在OnSuccess的时候,会默认执行如下方法:

function asyncOnSuccess(element, data, contentType) {
        var mode;

        if (contentType.indexOf("application/x-javascript") !== -1) {  // jQuery already executes JavaScript for us
            return;
        }

        mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase();
        $(element.getAttribute("data-ajax-update")).each(function (i, update) {
            var top;
            switch (mode) {
            case "BEFORE":
                top = update.firstChild;
                $("<div />").html(data).contents().each(function () {
                    update.insertBefore(this, top);
                });
                break;
            case "AFTER":
                $("<div />").html(data).contents().each(function () {
                    update.appendChild(this);
                });
                break;
            default:
                $(update).html(data);
                break;
            }
        });
    }

注意这里,UpdateTargetId如果不填或者没有找到元素,那么就不会发生任何事。这种情况适合服务器端返回的是json,xml等类型的数据而不是html,当我们拿到数据之后,需要通过JavaScript来生成要显示的html。

2. Ajax Form

Ajax Form的原理和ActionLink很像,唯一不同的是提交表单到一个地址,然后得到获得的数据:

@using (Ajax.BeginForm(new AjaxOptions { UpdateTargetId = "result" , Url=Url.Action("Result")}))
{
    @Html.EditorFor(m => m)
    <input type="submit" value="submit" />   

}
<div id="result">
</div>

Action代码如下:

public string Result(Course course)
        {
            System.Web.Script.Serialization.JavaScriptSerializer s = new System.Web.Script.Serialization.JavaScriptSerializer();
            return s.Serialize(course);
        }

[转]深入ASP.NET MVC之九:Ajax支持

时间: 2024-09-30 04:15:49

[转]深入ASP.NET MVC之九:Ajax支持的相关文章

ASP.NET MVC学习之Ajax(完结)

一.前言 通过上面的一番学习,大家一定收获不少.但是总归会有一个结束的时候,但是这个结束也意味着新的开始. 如果你是从事ASP.NET开发,并且也使用了第三方控件,那么一定会觉得ASP.NET开发ajax十分的简单,而ASP.NET MVC学习到现在页面都是刷新的,所以这节就是ASP.NET MVC的最后一节,通过这节的学习我们将能够实现通过ajax提交表单,下面我们开始继续学习. 二.准备工作 1.首先确保引用了以下js库在_Layout中: 2.新建一个HomeController,然后在其

ASP.NET MVC 此安装不支持该项目类型解决方法

http://www.cnblogs.com/younggun/archive/2011/03/03/1969498.html ASP.NET MVC  此安装不支持该项目类型解决方法 打开 .csproject 文件  在  <ProjectTypeGuids>中的三个GUID的前两个修改为: {F85E285D-A4E0-4152-9332-AB1D724D3325};{349c5851-65df-11da-9384-00065b846f21}; 后面还有一个 GUID 是你项目的GUID

asp.net MVC之整合AJAX

本文转自 http://www.cnblogs.com/leoo2sk/archive/2008/11/03/1325840.html 摘要本文将从完成“输入数据验证”这个功能出发,逐渐展开ASP.NET MVC与Ajax结合的方法.首先,本文将使用ASP.NET MVC提供的同步方式完成数据验证.而后,将分别结合ASP.NET AJAX和JQuery将这个功能重构成异步形式. 数据验证 原来录入页面时没有数据验证的:在标题或内容没有输入的情况下仍能保存.如下图 首先,我们要修改一下Releas

ASP.NET MVC 4 (九) 模型绑定

模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Inde

[转]ASP.NET MVC 4 (九) 模型绑定

本文转自:http://www.cnblogs.com/duanshuiliu/p/3706701.html 模型绑定指的是MVC从浏览器发送的HTTP请求中为我们创建.NET对象,在HTTP请求和C#间起着桥梁的作用.模型绑定的一个最简单的例子是带参数的控制器action方法,比如我们注册这样的路径映射: routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: n

asp.net MVC 使用JQuery.Ajax

使用到:Jquery.js 以及 Newtonsoft.Json.dll 客户端调用方式: $("#ButAjax").click(function() {$.ajax({type: "POST", //默认是GETurl: "/AjaxTest/getPerson",data: "ID=1&FirstName=C&LastName=HY",async: true, //异步cache: false, //不加

ASP.NET MVC之Unobtrusive Ajax(五)

前言 这一节我们来讲讲Unobtrusive中的Ajax提交,大部分情况下我们是利用JQuery来进行Ajax请求,当然利用JQuery来进行表单Ajax请求也不例外,但是相对于Unobtrusive Ajax来进行表单请求则Unobtrusive Ajax代码量显得更加精简,所以基于这点本文来讲讲这个Unobtrusive Ajax. 话题 我们首先一步一步深入来讲述我们本节的话题,我们在Models文件夹下建立如下一个类: public class Blog { public long Id

自坑实录 - Asp.net MVC中无法使用@Ajax.BeginForm问题解决

创建空的web项目,通过Nuget引用mvc组件来搭建空的MVC项目时, 在视图页面中无法使用@Ajax.BegForm来进行异步提交数据, 而新建默认的MVC模板项目却能够正常使用@Ajax.BegForm, 所有的引用都是齐全的,那么问题出在哪里呢? ..................... <script src="~/Scripts/jquery.min.js"></script> <script src="~/Scripts/jque

ASP.NET MVC Controller接收ajax post方式发送过来的json对象或数组数据

本例旨在说明我的一种Controller接收ajax提交(POST)过来的json对象或数组信息的方式,感觉应该有更好的方式,欢迎提出宝贵意见. JSON.stringify(jsonObj)不支持IE8以下浏览器 前端页面代码如下: 1 <script type="text/javascript" src="~/Scripts/jquery-1.11.3.js"></script> 2 <form id="fm"&