在Web系统中,Ajax技术已经成为提高用户体验的必备技术。开发Ajax程序,涉及两方面的内容:一是客户端技术,二是服务器端技术。

(1)客户端技术

核心工作是通过JavaScript向服务器发送数据和接收数据。初次之外还涉及两个工作,一是数据的展示,因此涉及Html DOM、CSS等相关技术;二是数据处理,因此涉及JSON、XML等数据格式处理技术。在实际开发过程中,可以借助一些客户端框架,来提高工作效率。

(2)服务器端技术

核心工作是完成在服务器端接收和发送数据。

10.1 使用动作方法处理Ajax请求

在动作方法中处理Ajax请求,重点关注的是如何向客户端返回数据。

对于接收数据,由于Ajax客户端程序仍是通过Get或Post方式发送数据,因此处理方式和接收非Ajax请求一致。

向服务器端发送数据,一般有如下几种形式。

10.1.1 返回纯文本数据

对于向客户端返回结构单一的数据,可以使用纯文本格式,如删除操作是否成功的提示,用法如示例1所示。

示例1

public ActionResult Delete(int? id)

{

//省略代码

if(manager.Delete(id))

{

return Content("1"); //操作成功

}

return Content("0");

}

对于示例1,客户端接收的数据是"0"或"1",根据数据客户端可做出删除操作是否成功的提示。

10.1.2 返回分部视图

对于局部刷新的效果,多数情况是向服务器端请求一个局部的页面,示例2展示了针对Ajax请求返回一个分部视图。

示例2

/// 获取当前用户的分组信息

public ActionResult ListGroups()

{

User user = Session["CurrentUser"] as User;

if (user == null)

{

return this.Content("<script>window.location='" + Url.Action("Login", "Account") + "'</script>");

}

int userId = user.UserId;

//分组列表数据

var groups = context.PrivateGroups.Where(a => a.OwnerId == userId).ToList();

//返回分部视图

return PartialView("GroupList");

}

注意使用PartialView()方法返回分部视图。

10.1.3 返回结构化数据

如果向客户端返回复杂结构的数据,一般需要由服务器端向客户端返回客户端支持的数据格式,如JSON格式和XML格式。在不同的服务器端平台中,都有相应的API 支持将对象转化成这些格式的数据。如示例3所示。

示例3

/// 获取当前用户分组信息

public ActionResult ListGroupsToJson()

{

User user = Session["CurrentUser"] as User;

if (user == null)

return Content("");

int userId = user.UserId;

//分组列表数据

var groups = (from g in context.PrivateGroups

where g.OwnerId == userId

select g

).ToList();

return Json(groups,JsonRequestBehavior.AllowGet);

}

示例3中, Json()方法负责将对象序列化为JSON数据,其中第一个参数是要序列化的对象,第二个 JsonRequestBehavior 类型的参数,是一个枚举类型,包含AllowGet 和 DenyGet 两个值,分别代表允许Get 请求和不允许 Get 请求。

客户端获取JSON数据后,一般需要对JSON数据进行处理,以某种形式展示出来。多数情况会使用客户端控件来处理,比如 BootStrapTables 。

 
 

在使用ASP.NET MVC 提供的 Json()方法返回JSON数据时,对待DateTime类型的数据处理往往不能满足我们的要求。在实际开发中我们通常会使用 如下方法:

Newtonsoft.Json.JsonConvert.SerializeObject(object value)

示例3中的最后一行代码可以换做如下:

return Content( JsonConvert.SerializeObject(groups) );

 
 

10.2 使用AjaxHelper

总的来说,在Ajax程序开发中,客户端的编码工作是必不可少的,但是如果使用ASP.NET MVC 框架,这些编码工作就会大大减少,甚至在一些简单的应用场景,不需要手工编写JavaScript 代码。

ASP.NET MVC 的这种功能是由 AjaxHelper 类型的对象提供的,此类和 HtmlHelper 是对应的,也是辅助视图输出的,特殊的是它用于生成具有Ajax功能的视图。相应地,在视图基类 WebViewPage 中包含名称为 AjaxHelper 类型的对象 Ajax ,通过Ajax 对象调用相应的方法实现Ajax 功能视图的输出。

10.2.1 构造无刷新表单

最常见的一种场景是表单提交,在客户端使用jQuery 时,一般会借助于 $.ajax() 和 $.post() 提交表单。其中,大部分的编码工作是从表单中获取提交的数据,工作量往往随着表单的字段增加而增加。

在ASP.NET MVC 中,借助于 Ajax 对象提供的 BeginForm()方法,即可完成此功能。如下语法展示了BeginForm() 一个典型的重载版本定义。

 
 

public static MvcForm BeginForm(

this AjaxHelper ajaxHelper,

string actionName,

object routeValues,

AjaxOptions ajaxOptions

)

和 HtmlHelper 中的BeginForm() 不同的是,多了AjaxOption 类型的参数,通过该类对请求发送前后进行相关的设置,主要属性如表10-1 所示。

表10-1 AjaxOptions 类的主要属性

主要属性

说 明

string UpdateTargetId

服务器响应来更新的 DOM 元素的 ID

string Confirm

提交请求之前显示在确认窗口中的消息

string HttpMethod

HTTP 请求方法("Get"或"Post")

InsertionMode InsertionMode

将响应插入目标 DOM 元素的模式,默认为Replace

int LoadingElementDuration

控制在显示或隐藏加载元素时的动画持续时间(毫秒)

string OnBegin

在更新页面之前调用的 JavaScript 函数

string OnSuccess

在成功更新页面之后调用的 JavaScript 函数

string OnComplete

在实例化相应数据后但在更新页面前调用的JavaScript函数

string OnFailure

在页面更新失败时调用的JavaScript 函数

string Url

向服务器发送请求的

 
 

示例4展示了 Ajax.BeginForm()的使用方法。

示例4

@section scripts{

<script type="text/javascript"

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

}

@using (Ajax.BeginForm("AddRecord",

new AjaxOptions { UpdateTargetId = "AddRecordMessage" }))

{

<textarea name="Content" cols="" rows="" class="importArea">

在想什么呢?记下来吧</textarea>

<p>

<input type="submit" value="发 表 "/ class="button">

<a id="AddRecordMessage" class="message"></a></p>

}

//动作方法-添加记录

[HttpPost]

public ActionResult AddRecord(string Content)

{

if (ModelState.IsVaild)

{

Record record= new Record();

record.Content=Content;

db.Records.Add(record);

if (db.SaveChanges()>0)

{

return Content("记录保存成功!");

}

Else

{

return Content("记录保存失败!");

}

}

else

{

return Content("请按要求填写信息!");

}

}

在示例4中,只用到 AjaxOption 类型的一个参数 UpdateTargetId ,其值为<a>标签的Id属性,<a>标签用于显示Ajax 方式提交后,从服务器端返回的消息提示。

需要注意使用ASP.NET MVC 提供的 Ajax 功能,需要引入 jquery.unobtrusive-ajax.min.js 脚本,该文件提供非侵入方式提供 Ajax 功能,而不生成Html 和 JavaScript 混合的代码,这和验证框架处理方式是一致的。示例4中 Ajax.BeginForm() 方法生成的Html 代码如下。

 
 

<form action="/Home/AddRecord"

data-ajax="true" data-ajax-mode="replace"

data-ajax-update="#AddRecordMessage"

id="form0" method="post">

<!--省略代码-->

</form>

对于一些简单的应用场景,使用 Ajax.BeignForm()方法基本不需要手工编写任何 JavaScript 脚本,但对一些特殊需求,还是需要编写 JavaScripts 函数实现,这些函数可以通过 AjaxOptions 的属性赋值进行调用。示例5 展示了 AjaxOptions 的 OnSucess 属性和 Confirm 属性的用法。

示例5

<script type="text/javascript">

function addRecordSuccess(data) {

$("#AddRecordMessage").html(data).show().hide(5000);

}

</script>

@using (Ajax.BeginForm("AddRecord", new AjaxOptions {

OnSuccess = "addRecordSuccess", Confirm="确认要提交么?" }))

{

<textarea name="Content" cols="" rows="" class="importArea">

在想什么呢?记下来吧

</textarea>

<p>

<input type="submit" value="发 表 "/ class="button">

<a id="AddRecordMessage" class="message"></a>

</p>

}

在示例5代码中,OnSucess 属性设置为 JavaScript 函数 addRecordsSuccess(), 使用函数实现消息显示后在5秒内自动隐藏。另外,使用 Confirm 弹出提交前的确认提示框。

10.2.2 生成无刷新链接

除了表单提交外,还有一个典型的应用场景,当点击一个链接时,在同一个页面局部加载页面内容。对于这种场景,Ajax对象提供了两种生成Ajax链接的方法,即 Ajax.ActionLink() 和 Ajax.RouteLink() ,和Html对象的两个对应的方法相比,多了一个AjaxOption参数。如示例6所示。

示例6

<ul class="friendCatalog" id="groupItems">

@foreach (Friends.Models.PrivateGroup m in ViewBag.Groups)

{

<li>

@Ajax.ActionLink(m.GroupName,"ListFriends","Friend",

new{groupId=m.GroupId},

new AjaxOptions(){OnSuccess="loadFriendsByGroup"})

<img src="@Url.Content("~/images/edit.gif")" />

<img src="@Url.Content("~/images/delete.gif")" /><span>

@m.FriendRelations.Count()</span>

</li>

}

<!--省略部分代码-->

</ul>

示例6运行后,Ajax.ActionLink()对应生成的Html代码如下所示。

<a data-ajax="true" data-ajax-success="loadFriendsByGroup"

href="/Friend/ListFriends?groupId=4">链接内容</a>

 
 

 
 

 
 

 
 

 
 

 
 

 
 

 
 

APS.NET MVC + EF (10)---使用AJAX的更多相关文章

  1. APS.NET MVC + EF (14)---项目框架搭建

    一:框架搭建     1:先创建Model. 2:创建数据访问接口层.IUserInfoDal 在该接口中定义了常见的方法CURD以及分页方法. public interface IUserInfoD ...

  2. APS.NET MVC + EF (08)---数据注解和验证

    对于Web开发人员来说,用户输入验证一直是一个挑战.不仅在客户端浏览器中需要执行验证逻辑,在服务器端也需要执行.如果觉得验证是令人望而生畏的繁杂琐事,ASP.NET MVC框架提供了数据注解的方式帮助 ...

  3. APS.NET MVC + EF (07)---表单和HTML辅助方法

    在ASP.NET MVC中,可以借助HtmlHelper 对象来输出页面内容,提高开发效率.下面,我们将介绍一些常用的辅助方法. 7.1 HTML辅助方法 BeginForm 该辅助方法主要用来产生& ...

  4. APS.NET MVC + EF (02)---深入理解ADO.NET Entity Framework

    2.7 深入理解Entity Framework 性能问题几乎是一切ORM框架的通病,对于EF来说,引起性能低的原因主要在以下几个方面. 复杂的对象管理机制为了在.NET中更好地管理模型对象,EF提供 ...

  5. APS.NET MVC + EF (02)---ADO.NET Entity FrameWork

    2.1 Entity Framework简介 Ado.net Entity Framework 是Microsoft推出的ORM框架. 2.1.1 什么是ORM 对象关系映射(Object Relat ...

  6. APS.NET MVC + EF (06)---模型

    在实际开发中,模型往往被划分为视图模型和业务模型两部分,视图模型靠近视图,业务模型靠近业务,但是在具体编码上,它们之间并不是隔离的. 6.1 视图模型和业务模型 模型大多数时候都是用来传递数据的.然而 ...

  7. APS.NET MVC + EF (11)---过滤器

    过滤器本质就是对动作方法的执行过程进行干预,这种干预可以影响动作方法执行的各个过程.ASP.NET MVC 提供了4种类型的接口,并在接口中定义了各种成员,代表代码执行的各个阶段,这些接口和成员如表1 ...

  8. APS.NET MVC + EF (05)---控制器

    Controller(控制器)在ASP.NET MVC中负责控制所有客户端与服务端的交互,并且负责协调Model与View之间数据传递,是ASP.NET MVC框架核心.Controller为ASP. ...

  9. APS.NET MVC + EF (04)---路由和数据传递

    4.1 视图引擎 ASP.NET MVC 提供两种视图引擎:ASPX(C#)和Razor(CSHTML),推荐使用Razor. 4.1.1 Razor的语法 在Razor视图中,所有的服务器端代码都是 ...

随机推荐

  1. [TCP/IP] 关闭连接后为什么客户端最后还要等待2MSL

    MSL(Maximum Segment Lifetime)报文最大生存时间,2MSL即两倍的MSL,TCP允许不同的实现可以设置不同的MSL值. 第一,保证客户端发送的最后一个ACK报文能够到达服务器 ...

  2. ios webview

    //#pragma mark - UIWebView Delegate Methods -(void)webViewDidFinishLoad:(UIWebView *)webView{ //获取到w ...

  3. Unity检视面板的继承方法研究 (一)

    对于检视面板 Inspector 的面板继承方式对项目来说是很有必要的, 比如一个基类, 写了一个很好看的检视面板[CustomEditor(typeof(XXX))], 可是所有子类的面板无法直接继 ...

  4. c# 第16节 一维数组的声明及使用

    本节内容: 1:为什么要有使用数组 2:数组的简介 3:一维数组的声明 4: 实例数组声明 5:一维数组的使用 6:一维数组使用注意地方 1:为什么要使用数组 2:数组的简介 3:一维数组的声明 4: ...

  5. 201871010132-张潇潇-《面向对象程序设计(java)》第七周总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  6. 接口规范、容错处理规则、aph备份数据规则

    前话:前后解耦,前端开发环节使用APH,后台开发环节postman(可考虑为后台也做一个aph后台版) 1.api标准:标识符(ret:1为正常数据,0为接口报错),数据体(data:api的数据容器 ...

  7. Python进阶-XIV 面向对象初步

    1.面向对象的引入 def Person(*args): ''' 定义一个人 :param args: 人的属性 :return: 人的所有属性的字典 ''' info = {} info['name ...

  8. bdd框架之lettuce

    安装 执行 :lettuce  (需要在特定的文件夹下) 结果指定到文件中

  9. <Stack> 150 71 388

    150. Evaluate Reverse Polish Notation class Solution { public int evalRPN(String[] tokens) { Stack&l ...

  10. Linux--部署Django项目

    简单部署 1.安装虚拟环境virtualenvwrapper,创建虚拟环境目录,进入虚拟环境,我的虚拟环境目录叫venv2 [root@HH ~]# workon venv2 (venv2) [roo ...