一、Ajax的前世今生
我一直觉得google是一家牛逼的公司,为什么这样说呢?《舌尖上的中国》大家都看了,那些美食估计你是百看不厌,但是里边我觉得其实也有这样的一个哲学:关于食材,对于种食材的菜农来讲,可能它的价值就是卖到市场上而已;而对于大厨们来讲,却可以像变魔术一样将不起眼的食材变成美味佳肴。大厨们不拥有食材,但他们却可以恰到好处的搭配使用它们,这就是他们的精明之处。而google同样是IT界的大厨:java诞生了这么多年,却没有被充分利用,而google却用它搞出来了震惊世界的Android; HTML、XML、Javascript这些个东东都不是google发明的吧,但却是google却用它们发明了Ajax, google earth、google suggest以及gmail等ajax技术的广泛应用,向这个世界带来了ajax技术,从此ajax与web再也不能分离。这里也向我们程序猿提了个醒:如果不能把所学的各种技术转化为money或者生产力,那么一切都是扯淡!
精确的说,ajax并不能提高从服务器端下载数据的速度,而只是使这个等待不那么令人沮丧,这就是所谓的用户体验了,但就这一点就足以产生巨大的影响和震动,因为它已经革了c/s东东的命,它无疑是WEB时代的宠儿~
Ajax的给我们带来的好处大家基本上都深有体会,略表一二:
1、最大的一点是页面无刷新,在页面内与服务器通信,给用户的体验非常好。
2、使用异步方式与服务器通信,不需要打断用户的操作,具有更加迅速的响应能力。
3、可以把以前一些服务器负担的工作转嫁到客户端,利用客户端闲置的能力来处理,减轻服务器和带宽的负担,节约空间和宽带租用成本。并且减轻服务器的负担,ajax的原则是“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器造成的负担。
4、基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。
缺点也有,但是瑕不掩瑜,所以还是要用!ASP.NET MVC作为微软的当家利器自然也要拥抱Ajax了,这里就说说他们之间那些事儿!
二、ASP.NET MVC之Ajax
这里不会用原生的Ajax的,其实我连说都不想说,土的掉渣,更别提那个微软自己的那个已经玩完的Ajax框架了,所以下面的Ajax都不是原生的。
1、基于AjaxHelper的Ajax
MVC框架本身提供了AjaxHelper类用于Ajax异步请求,所以如果你想省事,就用这种方式吧~
AjaxHelper帮助器方法:
Helper method |
Description |
Ajax.ActionLink |
Creates a hyperlink to a controller action that fires an Ajax request when clicked |
Ajax.RouteLink |
Similar to Ajax.ActionLink, but generates a link to a particular route instead of a named controller action |
Ajax.BeginForm |
Creates a form element that submits its data to a particular controller action using Ajax |
Ajax.BeginRouteForm | Similar to Ajax.BeginForm, but creates a form that sub- mits its data to a particular route instead of a named control- ler action |
Ajax.GlobalizationScript | Creates an HTML script element that references a script that contains culture information |
Ajax.JavaScriptStringEncode | Encodes a string to make sure that it can safely be used inside JavaScript |
上面的方法貌似很多,但是实际开发中用到的就两个帮助器方法而已:
Ajax.ActionLink()和Ajax.BeginForm()
这里有个问题:怎样让项目知道我们用的是MVC自带的Ajax呢?
SO EASY:
A、在Web.config里边配置:
<add key="UnobtrusiveJavaScriptEnabled" value="true" />
B、在页面中引用下面的js类库即可:
@section scripts{
<script type="text/javascript" src=" @Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
}
一般更为常见的是在布局页/Views/Shared/_Layout.cshtml 中引入,例如:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
<script src="~/Scripts/jquery-1.8.2.min.js"></script>
<script src="~/Scripts/jquery.unobtrusive-ajax.min.js"></script>
</head>
<body>
@RenderBody()
</body>
</html>
Ajax.ActionLink():
向客户端输出一个链接地址,当单击这个链接时可以Ajax调用Controller中的方法,Ajax.ActionLink()方法有许多重载,下面是其重载之一:
public static string ActionLink(this AjaxHelper ajaxHelper, string linkText, string actionName, object routeValues, AjaxOptions ajaxOptions);
linkText:是显示在客户端的文本
actionName:是Action的名字,默认情况下我们会使用当前的Controller。
routeValues:将传入到Controller中方法的参数
ajaxOptions:配置Ajax的一些选项
Confirm |
获取或设置提交请求之前,显示在确认窗口中的消息。 |
HttpMethod |
获取或设置 HTTP 请求方法(“Get”或“Post”)。 |
InsertionMode |
获取或设置指定如何将响应插入目标 DOM 元素的模式。 |
LoadingElementId |
获取或设置加载 Ajax 函数时要显示的 HTML 元素的 id 特性。 |
OnBegin |
获取或设置更新页面之前,恰好调用的 JavaScript 函数的名称。 |
OnComplete |
获取或设置实例化响应数据之后但更新页面之前,要调用的 JavaScript 函数。 |
OnFailure |
获取或设置页面更新失败时,要调用的 JavaScript 函数。 |
OnSuccess |
获取或设置成功更新页面之后,要调用的 JavaScript 函数。 |
UpdateTargetId |
获取或设置要使用服务器响应来更新的 DOM 元素的 ID。 |
Url |
获取或设置要向其发送请求的 URL。 |
备注:
- OnComplete和OnSuccess的区别:OnComplete是获取了Http请求时引发的,此时页面还没有进行更新,OnSuccess是在页面已经更新后引发的。
- 当加载数据须要花较长时候,为了避免假死状况,该当给用户一个反馈信息,如“正在加载...”字样。在 MVC 的 Unobtrusive Ajax 中经用AjaxOptions选项的 LoadingElementId 和 LoadingElementDuration 两个属性可轻松做到这一点,例如下面的设置:
AjaxOptions ajaxOpts = new AjaxOptions {
UpdateTargetId = "tableBody",
Url = Url.Action("GetPeopleData"),
LoadingElementId = "loading",
LoadingElementDuration = ,
};
- 对于URL,如果我们设置如下:
AjaxOptions ajaxOpts = new AjaxOptions {
UpdateTargetId = "tableBody",
Url = Url.Action("GetPeopleData")
};
然后查看它生成的 form 属性:
<form id="form0" action="/People/GetPeople" method="post" data-ajax-url="/People/GetPeopleData" data-ajax-="#tableBody"
data-ajax-mode="replace" data-ajax="true">
它生成了两个 Url,分别为 action 属性 和 data-ajax-url 属性的值,前者是 Ajax.BeginForm() 办法按照当前 controller 和 action 名称生成的,后者是 AjaxOptions 的 Url 属性生成的。当浏览器没有禁用 JavaScript 时,Unobtrusive Ajax JS库会获取 data-ajax-url 属性的值作为 Url 产生 ajax 恳求。当浏览器禁用了 JavaScript 时,天然 action 属性的值决定了默示提交的 Url,自然访问该页面。固然局部未能刷新,但不会让用户体验很差。
使用Html.ActionLink方法的一个栗子:
@Ajax.ActionLink("点击我", "getEntry", new { id = item.Id }, new AjaxOptions
{ HttpMethod = "Post", UpdateTargetId = "detailsID", InsertionMode = InsertionMode.Replace })
说明:“点击我”是生产的超链接文字;“getEntry”是当前控制器的Action方法;id = item.Id是向Action方法传递的参数;HttpMethod = "Post", 说明Ajax请求是post方式的;UpdateTargetId = "detailsID"说明了要更新的html块的Id标记元素;InsertionMode = InsertionMode.Replace说明是替换ID为detailsID的元素里边的内容。
实际应用:
(1)使用Ajax.ActionLink请求返回值为 Json格式的Controller方法
在Index.cshtml中使用ActionLink,如下:
@Ajax.ActionLink("点击我", "JsonDetails", new { id = item.Id },
new AjaxOptions { HttpMethod = "Post", InsertionMode = InsertionMode.Replace, OnSuccess = "Show" })
相应的Controller:
public ActionResult JsonDetails(int id = )
{
GuestbookEntry entry = _db.Entries.First(c => c.Id == id);
return Json(entry, JsonRequestBehavior.AllowGet);
}
同时需要在Index.cshtml中添加请求成功的相应js函数Show,以便更新ID属性为detailsID的DIV内容:
<script type="text/javascript">
function Show(data) {
$("#detailsID").html("姓名:" + data.Name + " 消息:" + data.Message);
}
</script>
(2)使用Ajax.ActionLink 请求返回值为PartialView格式的Controller方法
在Index.cshtml中
@Ajax.ActionLink("AjaxPartialView", "Details", new { id = item.Id },
new AjaxOptions { HttpMethod = "Get", UpdateTargetId = "detailsID" })
相应的Controller:
public ActionResult Details(int id = )
{
GuestbookEntry entry = _db.Entries.First(c => c.Id == id);
if (Request.IsAjaxRequest())
{
return PartialView(entry);
}
return View(entry);
}
在这里我们使用Request.IsAjaxRequest()来判断是否为Ajax请求,如果是则返回PartialView,否则返回View。最后,返回的内容会直接更新到ID属性为detailsID的DIV中。
Ajax.BeginForm
这个方法用于异步提交表单,比如一个新增信息的页面Create.cshtml,下面的代码会使表单以Ajax方式提交
@model MvcApplication5.Models.GuestbookEntry
<script type="text/javascript" src=" @Url.Content("~/Scripts/jquery.unobtrusive-ajax.js")"></script>
<script type="text/javascript">
function success(data) {
alert(data);
}
</script>
@{
ViewBag.Title = "Create";
} <h2>Create</h2> @using (Ajax.BeginForm(new AjaxOptions {
HttpMethod="Post",
OnSuccess = "success"
}))
{
@Html.ValidationSummary(true) <fieldset>
<legend>GuestbookEntry</legend>
<div class="editor-label">
@Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Name)
@Html.ValidationMessageFor(model => model.Name)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.Message)
</div>
<div class="editor-field">
@Html.EditorFor(model => model.Message)
@Html.ValidationMessageFor(model => model.Message)
</div>
<p>
<input type="submit" value="Create" />
</p>
</fieldset>
}
控制器的代码如下:
[HttpPost]
public ActionResult Create(GuestbookEntry entry)
{
if (ModelState.IsValid)
{
entry.DateAdded = DateTime.Now;
_db.Entries.Add(entry);
_db.SaveChanges();
return Content("New Entry successfully added.");
}
else {
return View();
}
}
注:
貌似上面的Ajax方法很方便,但是它的工作原理可能大家不是很清楚,这里就大概说一下吧~
当调用 Ajax.BeginForm 方法后,经由选项 AjaxOptions 对象设置的属性将会被转化成 form 表单的属性,这些属性以 data-ajax 开首,如本示例生成的 form 表单:
<form action="/GuestBook/Create" data-ajax="true" data-ajax-mode="replace" data-ajax-="#tableBody" id="form0" method="post">
当 Create.cshtml 视图加载完成并浮现 Html 页面时,jquery.unobtrusive-ajax.js 库会寻找所有 data-ajax == true的元素,然后按照其它以 data-ajax 开头的属性值,jQuery 库中的函数将知道如何去执行 Ajax 请求。
2、基于JQuery的Ajax
(1)使用JQuery的Ajax请求返回值为 Json格式的Controller方法
原理就是用JQuery的Ajax方法请求Action方法,返回值设为JSON,然后对JSON数据进行处理,例如用js函数进行处理
举个栗子:
<script type="text/javascript" language="javascript">
$(function(){
GetRoomInfoList();
});
function GetRoomInfoList() {
showDivLoading();//异步加载数据时的浮层
$.ajax({
type: "Post",
url: "@Url.Content("~/Room/GetRoomInfoShipId")",//异步请求的URL,就是Room控制器方法GetRoomInfoShipId(long shipId)
dataType: "json",//要求返回数据为JSON格式
data:{shipId:$("#ShipIdForSearch").val()},//异步请求的参数
success: function(data){
$("#RoomInfoListTable").empty(); //清空里面的所有内容
$.each(data, function(i, item){ //用js拼字符串处理数据,这里是显示所有房型列表信息 var str="<tr>";
str+=" <td>";
str+=" <span style=\" width:150px;display:block;white-space:nowrap; overflow:hidden; text-overflow:ellipsis;\">";
str+=item.BaseRoomId;
str+=" </span>"
str+=" </td>";
str+=" <td>";
str+=" <span style=\" width:150px;display:block;white-space:nowrap; overflow:hidden; text-overflow:ellipsis;\">";
str+=item.ShipId;
str+=" </span>"
str+=" </td>";
str+=" <td>";
str+=" <span style=\" width:150px;display:block;white-space:nowrap; overflow:hidden; text-overflow:ellipsis;\">";
str+=item.RoomType;
str+=" </span>"
str+=" </td>";
str+=" <td>";
str+=" <span style=\" width:150px;display:block;white-space:nowrap; overflow:hidden; text-overflow:ellipsis;\">";
str+=item.RoomName;
str+=" </span>"
str+=" </td>";
str+="</tr>";
$("#RoomInfoListTable").append(str);
});
}
}); }
(2)使用JQuery的Ajax 请求返回值为PartialView格式的Controller方法
假设有这样的一个Model:
namespace MvcApplication1.Models
{
public class Team
{
public string Preletter { get; set; }
public string Name { get; set; }
}
}
通过JQuery异步加载分部视图,Home/Index.cshtml:
@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Index</h2>
<div>
<a href="#" id="a">通过jQuery异步</a> <br/>
</div>
<div id="result">
</div>
@section scripts
{
<script type="text/javascript">
$(function() {
$('#a').click(function() {
$.ajax({
url: '@Url.Action("Index","Home")',
data: { pre: 'B' },
type: 'POST',
success: function(data) { $('#result').empty().append(data); }
}); return false;
});
});
</script>
}
HomeController控制器中:
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using MvcApplication1.Models;
namespace MvcApplication1.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(string pre)
{
var result = GetAllTeams().Where(t => t.Preletter == pre).ToList();
ViewBag.msg = "通过jQuery异步方式到达这里~~";
return PartialView("TeamY", result);
}
private List<Team> GetAllTeams()
{
return new List<Team>()
{
new Team(){Name = "巴西队", Preletter = "B"},
new Team(){Name = "克罗地亚队", Preletter = "K"},
new Team(){Name = "巴拉圭", Preletter = "B"},
new Team(){Name = "韩国", Preletter = "K"}
};
}
}
}
分部视图TeamY.cshtml:
@model IEnumerable<MvcApplication1.Models.Team>
@{
var result = string.Empty;
foreach (var item in Model)
{
result += item.Name + ",";
}
}
@ViewBag.msg.ToString()
<br/>
@result.Substring(,result.Length - )
3、基于JQuery的表单异步提交
举个栗子吧:
<script type="text/javascript">
$(document).ready(function () {
$("#form1").submit(function (event) {
event.preventDefault();//阻止默认提交事件,改用JS处理提交事件
$.ajax({
type:"Post//表单提交类型
url: "@Url.Content("~/User/Create")",//表单提交的Action方法
data:$("#form1").serialize(), //序列化表单的值为字符串,前提是表单里边的输入标签都要有name属性才可以,序列化后的形式大概是这样的:a=1&b=2&c=3&d=4&e=5
success:function(msg){
$("#result").html(msg);
}
});
return false;
});
});
</script>
但是我觉得如果表单提交的数据少的话,可以用这种,如果多的话,就没有必要了,用MVC自带的更好
三、如何提高Ajax性能
1、适当使用缓存机制
2、使用CDN内容分发来访问Jquery脚本:
(1)自己公司架设CDN服务器
(2)使用第三方公司的,比如微软,谷歌等公司的CDN,但有时候不太靠谱
3、JS/CSS文件的打包合并(Bundling)及压缩(Minification)
将多个JS或CSS文件打包合并成一个文件,并在网站发布之后进行压缩,从而减少HTTP请求次数,提高网络加载速度和页面解析速度。压缩功能实现了对javascript脚本和CSS进行压缩的功能,它能够去除脚本或样式中不必要的空白和注释,同时能够优化脚本变量名的长度
例如在BundleConfig.cs里面配置捆绑js和css文件:
using System.Web;
using System.Web.Optimization; namespace MvcExample
{
public class BundleConfig
{
// For more information on Bundling, visit http://go.microsoft.com/fwlink/?LinkId=254725
public static void RegisterBundles(BundleCollection bundles)
{
bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
"~/Scripts/jquery-{version}.js")); bundles.Add(new StyleBundle("~/Content/css").Include("~/Content/site.css"));
}
}
}
记得在Global.asax中注册一下:
BundleConfig.RegisterBundles(BundleTable.Bundles);
页面引用时可以这样引用:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>@ViewBag.Title</title>
@Styles.Render("~/Content/css")
@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
</head>
<body>
@RenderBody()
</body>
</html>
启用JS/CSS文件压缩合并:
- Web.config中配置
<compilation debug="false" targetFramework="4.0" />
- 在BundleConfig.cs或Global.asax中添加以下代码即可:
BundleTable.EnableOptimizations = true;
4、最好将js脚本文件放在view页面下面一点
关于ASP.NET MVC和Ajax的故事,暂且讲到这里吧!
ASP.NET MVC之Ajax如影随行的更多相关文章
-
MVC之Ajax如影随行
一.Ajax的前世今生 我一直觉得google是一家牛逼的公司,为什么这样说呢?<舌尖上的中国>大家都看了,那些美食估计你是百看不厌,但是里边我觉得其实也有这样的一个哲学:关于食材,对于种 ...
-
ASP.NET MVC 实现AJAX跨域请求方法《1》
ASP.NET MVC 实现AJAX跨域请求的两种方法 通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新.但有的时候需要向其它域发送AJAX请求,完成数据 ...
-
asp.net mvc 使用ajax请求 控制器 (PartialViewResult)分部的action,得到一个分部视图(PartialView)的HTML,进行渲染
在asp.net mvc 使用ajax请求获取数据的时候,我们一般是返回json或者xml,然后解析这些数据进行渲染,这样会比较麻烦,可以请求一个 分部action,返回一个分部视图 直接可以渲染,不 ...
-
在Asp.Net MVC中用Ajax回调后台方法
在Asp.Net MVC中用Ajax回调后台方法基本格式: var operData = ...; //传递的参数(action中定义的) var type = ...; //传递的参数(action ...
-
[代码示例]用Fine Uploader+ASP.NET MVC实现ajax文件上传
原文 [代码示例]用Fine Uploader+ASP.NET MVC实现ajax文件上传 Fine Uploader(http://fineuploader.com/)是一个实现 ajax 上传文件 ...
-
Asp.Net MVC 使用 Ajax
Asp.Net MVC 使用 Ajax Ajax 简单来说Ajax是一个无需重新加载整个网页的情况下,可以更新局部页面或数据的技术(异步的发送接收数据,不会干扰当前页面). Ajax工作原理 Ajax ...
-
Asp.Net MVC Unobtrusive Ajax
1. Unobtrusive JavaScript介绍 说到Unobtrusive Ajax,就要谈谈UnobtrusiveJavaScript了,所谓Unobtrusive JavaScript ...
-
ASP.NET MVC 实现 AJAX 跨域请求
ASP.NET MVC 实现AJAX跨域请求的两种方法 和大家分享下Ajax 跨域的经验,之前也找了好多资料,但是都不行,后来看到个可行的修改了并测试下 果然OK了 希望对大家有所帮助! 通常发送 ...
-
ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET MVC 学习笔记-6.异步控制器 ASP.NET MVC 学习笔记-5.Controller与View的数据传递 ASP.NET MVC 学习笔记-4.ASP.NET MVC中Ajax的应用 ASP.NET MVC 学习笔记-3.面向对象设计原则
ASP.NET MVC 学习笔记-7.自定义配置信息 ASP.NET程序中的web.config文件中,在appSettings这个配置节中能够保存一些配置,比如, 1 <appSettin ...
随机推荐
-
【Xcelsius】在PPT中嵌入水晶易表Xcelsius2008仪表盘
如果您使用Xcelsius创建了动画图形,并将其保存为 Shockwave® 文件(.swf 文件扩展名).但是往往插入进去之后,会产生一些比较棘手的问题,比如ppt不会自动播放,错误等等.今天把这些 ...
-
Spring AOP 实现功能权限校验功能
版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 使用拦截器实现未登录时跳转到登录界面的功能 1 拦截器SecurityInterceptor 2spring-mvcxml拦 ...
-
Codeforces 603A Alternative Thinking
题意:给你一个01串,必须替换一次,且替换的为子串.问换完后,最大01串长度. #include <bits/stdc++.h> typedef long long ll; using n ...
-
PHP数据结构预热:PHP的迭代器(转)
迭代器有时又称光标(cursor)是程式设计的软件设计模式,可在容器物件(container,例如list或vector)上遍访的接口,设计人员无需关心容器物件的内容. 各种语言实作Iterator的 ...
-
第一次写博客,关于前端开发deMVC在js中的应用
对前端MVC MVC分别是model.view.controller的缩写,模型.视图.控制器.这些更加偏向于后台,在以前MVC是只属于后台的.当然随着技术的进步,前端的大牛们将后台的一些东西应用于前 ...
-
全球性WannaCry蠕虫勒索病毒感染前后应对措施
前言:针对WannaCrypt勒索病毒的讨论和技术文章是铺天盖地,大量的技术流派,安全厂家等纷纷献计献策,有安全厂家开发各种安全工具,对安全生态来说是一个好事,但对个人未必就是好事,我们国家很多用户是 ...
-
js DOM常见事件
js事件命名为on+动词 1.onclick事件,点击鼠标时触发,ondbclick双击事件 <h1 onclick="this.innerHTML='点击后文本'"> ...
-
【洛谷】【动态规划(多维)】P1006 传纸条
[题目描述:] 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了.幸 ...
-
cognos report在做同比时遇到的问题解决方法
本例就拿简单的一个模型作为测试: 订单中包括日期key,商品类型key 现在要实现每月的订单数,以及去年同期的订单数: step1:新建2个数据项 本月,去年同月 本月: [每日订单数据分析].[日期 ...
-
HDU 4300 Clairewd’s message(扩展KMP)题解
题意:先给你一个密码本,再给你一串字符串,字符串前面是密文,后面是明文(明文可能不完成整),也就是说这个字符串由一个完整的密文和可能不完整的该密文的明文组成,要你找出最短的密文+明文. 思路:我们把字 ...