相信不少朋友在刚接触WebForm编程的时候都有过这样的想法,为什么在.aspx页面的Javascript中不能直接调用到.aspx.cs文件中的方法?这篇文章所介绍的内容与这个问题有点关系,但并没有真正的解决Javascript直接调用C#的方法这个问题,只是通过其它的方式让我们前端与后端的交互实现起来能更简单些,介绍的内容是本人在实际的开发过程中累积的一点点心得,分享出来,不对的地方或有更好的实现,大家不妨拿出来一起交流。
Ajax这个东西就不用我过多的介绍了,相信大家可能比我了解的还要多,当有一些静态(或伪静态)页面中有部分数据需要动态更新时,Ajax就用得比较多了,处理Ajax请求的方法也有很多种,有的朋友直接新建一个.aspx页面,然后在.aspx.cs文件中Response.Write,有的朋友则喜欢用.ashx文件来处理,也有的朋友喜欢用IHttpHandler。文章中使用的就是IHttpHandler。
一般需要动态输出的内容或多或少会跟业务逻辑有些关联,所以在示例中代码是分了两个项目,Web项目只负责数据的展示,Biz项目负责逻辑的处理。演示的代码仅作为简单示例,实际开发项目中的代码可能会有很大的差异。
下面进入正题,说说我们要实现的内容。
在html页面中我们可以通过指定规则的链接直接访问到Biz项目中的某个类的指定方法。
如请求/Ajax/News/GetNewsHits.aspx,则我们可以调用到Biz项目中的News类里的GetNewsHits方法。
既然大家都知道直接调用是不可能实现的了,那我们肯定需要一个代理来帮我们完成中间的过程。
首先,我们先在Web项目的根目录下建立一个Ajax文件夹,并在里面添加一个web.config文件。代码如下:
View Code
xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings/>
<connectionStrings/>
<system.web>
<httpHandlers>
<add path="*.aspx" validate="false" type="Biz.Factory" verb="*"/>
httpHandlers>
system.web>
<system.webServer>
<handlers>
<add name="AjaxRequestFactory" path="*.aspx" type="Biz.Factory" verb="*"/>
handlers>
system.webServer>
configuration>
这段代码表示Ajax文件夹下所有的aspx文件请求都交给“Biz.Factory”类来处理。
然后我们在Biz项目中加入类“Factory”,也就是我们的代理类,由它来负责将请求转接到指定的方法,并实现IHttpHandler接口。代码如下:
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
namespace Biz {
public class Factory : IHttpHandler {
public bool IsReusable {
get {
return true;
}
}
public void ProcessRequest(HttpContext context) {
Execute(context);
}
void Execute(HttpContext context) {
//根据请求的Url,通过反射取得处理该请求的类
string url = context.Request.Url.AbsolutePath;
string[] array = url.Split(new char[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
string typename = "Biz";
for (int x = 1; x < array.Length - 1; x++) {
typename += "." + array[x];
}
Type type = this.GetType().Assembly.GetType(typename, false, true);
if (type != null) {
//取得类的无参数构造函数
var constructor = type.GetConstructor(new Type[0]);
//调用构造函数取得类的实例
var obj = constructor.Invoke(null);
//查找请求的方法
var method = type.GetMethod(System.IO.Path.GetFileNameWithoutExtension(url));
if (method != null) {
//执行方法并输出响应结果
context.Response.Write(method.Invoke(obj, null));
}
}
}
}
}
当然,我们还需要一个用来做演示的被调用的类News:
View Code
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5
6 namespace Biz {
7 public class News {
8 static int _value;
9 public int GetNewsHits() {
10 return ++_value;
11 }
12 }
13 }
最后回到web项目中新建一个html文件,代码很简单,ajax就不重复敲代码了,直接用jquery里相关的方法:
View Code
DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "">
<html xmlns="">
<head runat="server">
<title>title>
<script language="javascript" type="text/javascript" src="Scripts/jquery-1.4.1.min.js">script>
<script language="javascript" type="text/javascript">
$(function () {
//绑定按钮点击事件
$("input:button").click(function () {
$.post("/Ajax/News/GetNewsHits.aspx", null, function (txt) {
$("div").text(txt);
}, "text");
});
});
script>
head>
<body>
<div style="font-size:24px;font-weight:bold;width:100px;line-height:35px;text-align:center;">0div>
<input type="button" value="获取点击次数" />
body>
html>
所有代码准备完成,实际上代码没几行,Biz项目中的类及方法可以随意添加,只需要更改调用的链接即可。
附示例代码下载:点击下载
示例代码说明:
1.需要运行项目才能看到演示效果。
2.每点击一次按钮服务端的变量就回累加1并返回。
3.您也可以在Biz.News类中加入另一个方法进行测试,当然调用链接中的GetNewsHits要修改成您对应的方法名。
4.您也可以在Biz项目中加入一个新的类来测试,条件是新的类必须有无参数构造函数。
未完待续...