使用Ajax
ASP.NET 使用Ajax
之前在Ajax初步理解中介绍了对Ajax的初步理解,本文将介绍在ASP.NET中如何方便使用Ajax,第一种当然是使用jQuery的ajax,功能强大而且操作简单方便,第二种是使用.NET封装好的ScriptManager。
$.ajax向普通页面发送get请求
这是最简单的一种方式了,先简单了解jQuery ajax的语法,最常用的调用方式是这样:$.ajax({settings}); 有几个常用的setting,全部参数及其解释可以去jQuery官方API文档查询
1. type:请求方式 get/post
2. url:请求的Uri
3. async:请求是否为异步
4. headers:自定义的header参数
5. data:发往服务器的参数
6. dataType:参数格式,常见的有string、json、xml等
7. contents:决定怎样解析response的一个”字符串/正则表达式” map
8. contentType:发送到服务器的额数据的内容编码类型,它的默认值是"application/x-www-form-urlencoded; charset=UTF-8""。
9. success:请求成功后调用的句柄
10.error:请求失败后调用的句柄
没使用过jQuery的ajax话这样看有些云里雾里的感觉,来看一个简单例子
首先使用Visual Studio新建一个WebApplication,把jQuery.js引入project,然后添加两个页面,Default.aspx作为测试用
Default.aspx
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Web.Default" %>
<!DOCTYPE html >
<html>
<head runat="server">
<title>Ajax</title>
<script src="jQuery.js" type="text/javascript"></script>
<style type="text/css">
html, body, form
{
width: 100%;
height: 100%;
padding: 0px;
margin: 0px;
} #container
{
margin: 100px;
height: 300px;
width: 500px;
background-color: #eee;
border: dached 1px #0e0;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div id="container">
<input type="button" value="Test Ajax" onclick="testGet()" />
<br />
</div>
<script type="text/javascript">
function setContainer(text) {
document.getElementById("container").innerHTML += ('<br/>' + text);
} function testGet() {
$.ajax({
type: 'get',
url: 'NormalPage.aspx',
async: true,
success: function (result) {
alert(result);
},
error: function () {
setContainer('ERROR!');
}
});
}
</script>
</form>
</body>
</html>
NormalPage.aspx作为请求页面,先不做任何处理。在Default.aspx页面中的JavaScript中可以看到testGet函数就利用jQuery的ajax向Normal.aspx发送了了一个get请求,没写的参数使用jQuery默认参数,这个调用没使用任何参数,简单向Normal.aspx页面发送请求,请求成功则alert全部response(即success方法参数:result,jQuery会把responseText传入success方法第一个参数),请求失败则向DIV中添加一行错误提示文本。如果一切正常,可以看到页面弹出对话框,对话框内内容即是Normal.aspx页面内容
一个简单的get请求完成了,这样的结果一般没有多大用处,也不是ajax意图所在,使用Ajax主要是想使用JavaScript可以异步向服务器发送特定请求,获取服务器相关数据,比如向服务器询问天气,然后获得天气数据,更新页面,而不是获取整个页面,换句话说,使用Ajax本身就是为了摆脱更新整个页面来更新页面数据这种模式,仅仅需要服务器给我们数据即可,这就需要调用服务器端的特定方法。
$.ajax GET请求调用服务器特定方法
我们这时候需要修改NormalPage.aspx,为其添加几个方法供Default.aspx测试调用
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls; namespace Web
{
public partial class NormalPage : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string action = Request.QueryString["action"];
Response.Clear(); //清除所有之前生成的Response内容
if (!string.IsNullOrEmpty(action))
{
switch (action)
{
case "getTime":
Response.Write(GetTime());
break;
case "getDate":
Response.Write(GetDate());
break;
}
}
Response.End(); //停止Response后续写入动作,保证Response内只有我们写入内容
} private string GetDate()
{
return DateTime.Now.ToShortDateString();
} private string GetTime()
{
return DateTime.Now.ToShortTimeString();
}
}
}
然后为Default.aspx添加一个新的方法,并修改button的onclick方法为新写的函数
function testGet2() {
$.ajax({
type: 'get',
url: 'NormalPage.aspx',
async: true,
data:{action:'getTime'},
success: function (result) {
setContainer(result);
},
error: function () {
setContainer('ERROR!');
}
});
}
testGet2函数是在testGet函数的基础上做了些许修改,首先对success方法做了更改,把得到的response写到页面;然后对请求添加了data参数,请求向服务器发送了一个action:getTime的键值对,在get请求中jQuery会把此参数转为url的参数,上面写法和这种写法效果一样
function testGet3() {
$.ajax({
type: 'get',
url: 'NormalPage.aspx?action=getTime',
async: true,
success: function (result) {
setContainer(result);
},
error: function () {
setContainer('ERROR!');
}
});
}
看一下执行效果,这是Chrome的监视结果
如果调试我们发现这个请求调用的服务器页面NormalPage.aspx的GETime方法,并且response中只包含对有用的数据,如果把请求中参数的值改为getDate,那么就会调用对应GetDate方法。
$.ajax POST与json
这样向一个页面发送请求然后在Load事件处理程序中根据参数调用不同方法,清除Response,写入Response,终止Response,而且传入的参数局限性太大,好业余的赶脚,看看专业些解决方法。为project添加一个General Handler类型文件,关于HttpHandler相关内容本文不做详细解释,只需知道它可以非常轻量级的处理HTTP请求,不用走繁琐的页面生命周期处理各种非必需数据。
Handler.ashx.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Newtonsoft.Json; namespace Web
{
/// <summary>
/// Summary description for Handler
/// </summary>
public class Handler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
Student stu = new Student();
int Id = Convert.ToInt32(context.Request.Form["ID"]);
if (Id == 1)
{
stu.Name = "Byron";
}
else
{
stu.Name = "Frank";
}
string stuJsonString= JsonConvert.SerializeObject(stu);
context.Response.Write(stuJsonString);
} public bool IsReusable
{
get
{
return false;
}
}
}
}
关于这个类语法本文不做详细说明,每次发起HTTP请求ProcessRequest方法都会被调用到,Post类型请求参数和一再Request对象的Form中取得,每次根据参数ID值返回对应json对象字符串,为了展示json格式数据交互,需要为项目引入json.net这一开源类库处理对象序列化反序列化问题,然后创建一个Student类文件
Student.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web; namespace Web
{
public class Student
{
public int ID { get; set; }
public string Name { get; set; }
}
}
看看页面如何处理
function testPost() {
$.ajax({
type: 'post',
url: 'Handler.ashx',
async: true,
data: { ID: '1' },
success: function (result) {
setContainer(result);
var stu =eval ('('+result+')');
setContainer(stu.ID);
setContainer(stu.Name);
},
error: function () {
setContainer('ERROR!');
}
});
}
结果是这个样子的
上面代码向Handler.ashx发送一Post请求,比且带有参数{ID:’1’},可以看到结果,如果用调试工具可以发现,得到的result是一个json格式的字符串,也就是往Response写的对象序列化后的结果。这样就实现了比较专业些的方式调用Ajax,但是有一个问题依旧存在,HttpHandler会自动调用ProcessRequest方法,但是也只能调用该方法,如果想调用不同方法只能像普通页面那样传递一个参数表明调用哪个方法,或者写不同的Handler文件。
WebService与ScriptManager
微软向来很贴心,看看微软怎么处理上面的困惑,那就是利用WebService,WebService配合SCriptManager有客户端调用的能力,在项目中添加一个Webservice文件
WebService.asmx
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services; namespace Web
{
/// <summary>
/// Summary description for WebService
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class WebService : System.Web.Services.WebService
{ [WebMethod]
public Student GetStudent(int ID)
{
if (ID == 1)
{
return new Student() { ID = 1, Name = "Byron" };
}
else
{
return new Student() { ID = 2, Name = "Frank" };
}
}
[WebMethod]
public string GetDateTime(bool isLong)
{
if (isLong)
{
return DateTime.Now.ToLongDateString();
}
else
{
return DateTime.Now.ToShortDateString();
}
}
}
}
代码中加黄的code默认是被注释掉的,要想让客户端调用需要把注释去掉,Service中定义了两个方法,写个测试方法让客户端调用第一个方法根据参数返回对应对象,首先需要在页面from内加上ScriptManager,引用刚才写的WebService文件
Default.aspx
<form id="form1" runat="server">
<asp:ScriptManager ID="clientService" runat="server">
<Services>
<asp:ServiceReference Path="~/WebService.asmx" />
</Services>
</asp:ScriptManager>
<div id="container">
<input type="button" value="Test Ajax" onclick="testPost2()" />
<br />
</div>
...
然后添加JavaScript测试代码
function testPost2() {
Web.WebService.GetStudent(1, function (result) {
setContainer(result.ID);
setContainer(result.Name);
}, function () {
setContainer('ERROR!');
});
}
测试代码中需要显示书写WebService定义方法完整路径,WebService命名空间.WebService类名.方法名,而出入的参数列表前几个是调用方法的参数列表,因为GetStudent只有一个参数,所以只写一个,如果有两个参数就顺序写两个,另外两个参数可以很明显看出来是响应成功/失败处理程序。看看执行结果:
观察仔细会发现使用ScriptManager和WebService组合有福利,在WebService中传回Student对象的时候并没有序列化成字符串,而是直接返回,看上面图发现对象已经自动转换为一json对象,result结果可以直接操作,果真非常贴心。而上一个例子中我们得到的response是一个json字符串,在客户端需要用eval使其转换为json对象。
ScriptManager+WebSefvice调用ajax带来了很大的便利性,但同时牺牲了很多灵活性,我们没法像jQuery那样指定很多设置有没有两全其美的办法呢
$.ajax+WebService
jQuery调用Handler几乎完美了,但是不能处理多个方法,上面例子我们可以发现WebService可以实现这一功能,那么能不能jQUery调用WebService的不同方法呢?答案是肯定的,试一试用jQuery调用刚才WebService定义的第二个方法。写一个测试函数
function testPost3() {
$.ajax({
type: 'post',
url: 'WebService.asmx/GetDateTime',
async: true,
data: { isLong: true },
success: function (result) {
setContainer($(result).find('string').text());
},
error: function () {
setContainer('ERROR!');
}
});
}
调用方式没有多大变化,简单依旧,只要把URL改为WebService路径+需要调用的方法名,然后把参数放到data里就可以了。我们看看结果:
通过上图可以看到,jQuery调用WebService默认会返回一个XML文档,而需要的数据在 <string>节点中,只需要使用jQuery解析xml的语法就可以轻松得到数据。如果希望返回一个json对象怎么办?那就得和调用Handler一样使用json.net序列化,然后前端使用eval转换了,也不会过于复杂。我在项目中最常使用这个模式,这样既保持了jQuery的灵活性又可以在一个Service中书写多个方法供调用,还不用走复杂的页面生命周期
json.net和本文示例源代码
json.net是一个开源的.net平台处理json的库,可以序列化Dictionay嵌套等复杂对象,关于其简单使用有时间会总结一下,可以自codeplex上得到其源码和官方说明。本文的源代码可以点击这里获得。
使用Ajax的更多相关文章
- jQuery之ajax实现篇
jQuery的ajax方法非常好用,这么好的东西,你想拥有一个属于自己的ajax么?接下来,我们来自己做一个简单的ajax吧. 实现功能 由于jq中的ajax方法是用了内置的deferred模块,是P ...
- Ajax及跨域
概念 Ajax Ajax,Asynchronous JavaScript and XML,字面意思:异步的 JavaScript 和 XML,是指一种创建交互式网页应用的网页开发技术. 用于异步地去获 ...
- 一个粗心的Bug,JSON格式不规范导致AJAX错误
一.事件回放 今天工作时碰到了一个奇怪的问题,这个问题很早很早以前也碰到过,不过没想到过这么久了竟然又栽在这里. 当时正在联调一个项目,由于后端没有提供数据接口,于是我直接本地建立了一个 json ...
- ABP文档 - Javascript Api - AJAX
本节内容: AJAX操作相关问题 ABP的方式 AJAX 返回信息 处理错误 HTTP 状态码 WrapResult和DontWrapResult特性 Asp.net Mvc 控制器 Asp.net ...
- ajax异步请求
做前端开发的朋友对于ajax异步更新一定印象深刻,作为刚入坑的小白,今天就和大家一起聊聊关于ajax异步请求的那点事.既然是ajax就少不了jQuery的知识,推荐大家访问www.w3school.c ...
- 调用AJAX做登陆和注册
先建立一个页面来检测一下我们建立的用户名能不能用,看一下有没有已经存在的用户名吗 可以通过ajax提示一下 $("#uid").blur(function(){ //取用户名 va ...
- Ajax 概念 分析 举例
Ajax是结合了访问数据库,数据访问,Jquery 可以做页面局部刷新或者说是页面不刷新,我可以让页面不刷新,仅仅是数据的刷新,没有频繁的刷页面,是现在比较常用的一种方式做页面那么它是怎么实现页面无刷 ...
- ajax
常见的HTTP状态码状态码:200 请求成功.一般用于GET和POST方法 OK301 资源移动.所请求资源移动到新的URL,浏览器自动跳转到新的URL Moved Permanently304 未修 ...
- 学习笔记之MVC级联及Ajax操作
由于刚转型到MVC,MVC的架构模式很多不是很清楚,比如今天就想做个级联的操作,因为之前的ASP.NET的方式是通过:控件-->添加事件-->后台编写级联事件进行触发,但是这个MVC就不同 ...
- javascript表单的Ajax 提交插件的使用
Ajax 提交插件 form.js 表单的下载地址:官方网站:http://malsup.com/jquery/form/ form.js 插件有两个核心方法:ajaxForm()和ajaxSubmi ...
随机推荐
- iOS、真机调试
Xcode中IOS.真机测试 一.购买开发者账号(需要有信用卡.每年支付$99.0) 二.直接淘宝购买一个.用于测试,但是不能上传App 1.获取手机的UUID(Identifier xxxxxx9e ...
- 分布式基础学习(2)分布式计算系统(Map/Reduce)
二. 分布式计算(Map/Reduce) 分 布式式计算,同样是一个宽泛的概念,在这里,它狭义的指代,按Google Map/Reduce框架所设计的分布式框架.在Hadoop中,分布式文件 系统,很 ...
- springMVC 获取本地项目路径 及后整理上传文件的方法
String path=request.getSession().getServletContext().getRealPath("upload/img/product"); // ...
- selenium之多线程启动grid分布式测试框架封装(一)
一.设计思路 在国内市场上,IE内核的浏览器占据了绝大部分的市场份额,那么此次框架封装将进行IE系列的浏览器进行多线程并发执行分布式测试的封装. 运行时主进程与多线程关系如下:
- 让Windows 8 / 8.1 以及 Windows Server 2012 / 2012 R2的任务管理器的性能面板,显示磁盘数据
运行[diskperf -y],关闭任务管理器,重新打开即可.
- 小猪Android越来越方式 Day 5 - part 2
小猪的Android入门之路 Day 5 - part 2 Activity片段:Fragment(碎片) ------转载请注明出处 ...
- SSIS如何引用外部DLL
原文:SSIS如何引用外部DLL 当SSIS引用外部的DLL时,外部的DLL须满足以下条件: 1. DLL是强命名. 2. 加入到GAC (C:\WINDOWS\assembly),直接把DLL拉进目 ...
- .Net中批量更新或添加数据
方法一:使用SqlBulkCopy实现批量更新或添加数据. SqlBulkCopy类一般只能用来将数据批量插入打数据库中,如果数据表中设置了主键,出现重复数据的话会报错,如果没有设置主键,那么将会添加 ...
- Solr 教程
1.Solr安装 下载jdk-8u111-windows-i586_8.0.1110.14 下载solr-6.3.0.zip 2.配置JAVA_HOME 在"系统变量"中,设置3项 ...
- 读书笔记—CLR via C#线程25-26章节
前言 这本书这几年零零散散读过两三遍了,作为经典书籍,应该重复读反复读,既然我现在开始写博了,我也准备把以前觉得经典的好书重读细读一遍,并且将笔记整理到博客中,好记性不如烂笔头,同时也在写的过程中也可 ...