在当前WEB当中,有些人都会抛弃asp.net的服务器控件,转而使用ajax来进行数据的交互和存储.

  当我们大量使用ajax的时候,对于新手而言,肯定会创建很多的ashx或aspx页面,通过拼接参数,在ashx或aspx中对参数进行解析,

  并根据某些特定的参数进行解析来判断当前的请求属于哪种类型的操作,然后手动获取Request.QueryString、Params、Form内的值,来实现功能.大致代码如下:

 1 //html
2 名字:<input id="name" type="text"/>
3 <input type="button" value="查询" onclick="search()"/>
4 <script type="text/javascript">
5 function search(){
6 var name = $('#name').val();
7 //省略验证过程
8 $.ajax({
9 url: 'Customer.ashx',
10 data: { type: 'search', name : name },
11 dataType: 'json',
12 success: function(json){
13 //对于获取的数据执行相关的操作,如:绑定、显示等
14 }
15 });
16 };
17 </script>
18 //ashx
19 public void ProcessRequest(HttpContext context)
20 {
21 var type = context.Request.Params["type"];
22 if(type == "search")
23 {
24 var name = context.Request.Params["name"];
25 //获取数据,并转化为json
26 var json = ...//省略
27 context.Response.Write(json);
28 }
29 }

在大量的重复这些编写这些代码的情况下,众多的新手们肯定都会跟我一样,蛋疼啊,而且随着业务及模块的不断增加,这些个ashx或aspx,那个量还不是一般的多呢.

  而且每个都只是做一些判断,根本没什么重要的业务在里面,于是乎我们就在想,有没有什么方法可以让我们在ajax内传递某些参数,达到直接反射类,访问对应的方法,自动处理参数等.

  根据以上的一些要求,的确可以让我们在编码过程当中,减少很多的困惑和麻烦.那我们现在就一步步开始吧.

  首先,我们先从ajax开始,传递某些特定的值来反射对应的类,那么我们的第一反应就是将类的整个完整命名传递过去(因为我们并不能保证所有要调用的类都在同一个程序集内).

  那么我们就在js内定义2个参数分别为assembly和fullName吧.我们假设Customer业务类的FullName为SysBLL.CustomerBLL且所在的程序集为SysBLL.

  那么前面的例子ajax的修改大致如下:

 1 <script type="text/javascript">
2 function search(){
3 var name = $('#name').val();
4 //省略验证过程
5 $.ajax({
6 url: 'BLLAshx.ashx',
7 data: { assemlby : 'SysBLL', fullName: 'SysBLL.CustomerBLL', method: 'Search', name : name },
8 dataType: 'json',
9 success: function(json){
10 //对于获取的数据执行相关的操作,如:绑定、显示等
11 }
12 });
13 };
14 </script>
从我们的需求上,我们了解到,我们只需要一个ashx来作为代理,去反射对应的类和方法,并从传递的参数中过滤出方法所需要的参数,最后调用方法取得返回值.代码大致如下:

 1
2 //ashx
3 namespace Common
4 {
5 public class BLLAshx : IHttpHandler
6 {
7 public void ProcessRequest(HttpContext context)
8 {
9 string assemblyName = context.Request.QueryString["assemlby"], fullName = context.Request.Params["fullName"];
10 var bllType = Assembly.Load(assemblyName).GetType(fullName);
11
12 var methodName = context.Request.Params["method"];
13 var method = bllType.GetMethod(methodName);
14 if (null != method)
15 {
16 string[] parameterValues = GetMethodParameterValues(context.Request, method);
17
18 var instance = Activator.CreateInstance(bllType);
19
20 var result = method.ReturnType == typeof(void) ? "{}" : method.Invoke(instance, parameterValues).ToString();
21
22 //以上Invoke省略了判断以及捕捉异常
23 context.Response.Write(result);
24 }
25 else
26 {
27 //返回不存在方法的提示
28 }
29 }
30
31 private string[] GetMethodParameterValues(HttpRequest request, MethodInfo method)
32 {
33 string[] parameterValues = null;
34 var methodParameters = method.GetParameters();
35 if (0 < methodParameters.Length)
36 {
37 parameterValues = new string[methodParameters.Length];
38 for (int i = 0; i < methodParameters.Length; i++)
39 {
40 parameterValues[i] = request.Params[methodParameters[i].Name];
41 }
42 }
43 return parameterValues;
44 }
45 }
46 }
47 //CustomerBLL
48 namespace SysBLL
49 {
50 public class CustomerBLL
51 {
52 public string Search(string name)
53 {
54 var json = ...//获取数据
55 return json;
56 }
57 }
58 }
 

对于以上的ashx,我们需要在web项目中,新建一个名为BLLAshx的ashx文件,但是我们不要.cs的文件,并作如下修改:

<%@ WebHandler Language="C#" CodeBehind="BLLAshx.cs" Class="Common.BLLAshx" %>

  现在我们再次回到ajax调用的地方,大家都会发现我们的参数列表室在太长了,因此大家可能会想用一些方法来改善,比如:连ashx都懒的重复去写了,想直接在url中把弥命名空间、类、方法直接放进去来替代,想到这一步的时候,我们就需要配置web.config了,假设我们想要的规则是SysBLL/SysBLL.CustomerBLL.Search,配置如下:

<httpHandlers>
<add path="*/*.*.*.do" type="Common.BLLAshx" verb="GET,POST"/>
</httpHandlers>

  有人会问为什么这边要.do,而不直接省略呢?因为如果不加.do,那么就会将其他的请求也都转向我们的ashx,例如:js、css文件等,大家可以自己测试看看.因为我们使用了地址映射,因此我们的js以及ashx代码又要做一些改动了.大致修改如下:

//ashx
namespace Common
{
public class BLLAshx : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string assemblyName = context.Request.QueryString["assemlby"], fullName = context.Request.Params["fullName"];
var bllType = Assembly.Load(assemblyName).GetType(fullName);

var methodName = context.Request.Params["method"];
var method = bllType.GetMethod(methodName);
if (null != method)
{
string[] parameterValues = GetMethodParameterValues(context.Request, method);

var instance = Activator.CreateInstance(bllType);

var result = method.ReturnType == typeof(void) ? "{}" : method.Invoke(instance, parameterValues).ToString();

//以上Invoke省略了判断以及捕捉异常
context.Response.Write(result);
}
else
{
//返回不存在方法的提示
}
}

private string[] GetMethodParameterValues(HttpRequest request, MethodInfo method)
{
string[] parameterValues = null;
var methodParameters = method.GetParameters();
if (0 < methodParameters.Length)
{
parameterValues = new string[methodParameters.Length];
for (int i = 0; i < methodParameters.Length; i++)
{
parameterValues[i] = request.Params[methodParameters[i].Name];
}
}
return parameterValues;
}
}
}
//CustomerBLL
namespace SysBLL
{
public class CustomerBLL
{
public string Search(string name)
{
var json = ...//获取数据
return json;
}
}
}

ashx的调整,我们只要修改ProcessRequest方法,代码大致如下:

var reg = new Regex(@"(?<assembly>\w+)\/(?<class>\w+\.\w+)\.(?<method>\w+)\.");
var groups = reg.Match(context.Request.AppRelativeCurrentExecutionFilePath).Groups;
if (4 == groups.Count)
{
string assemblyName = groups["assembly"].Value, fullName = groups["class"].Value;
var bllType = Assembly.Load(assemblyName).GetType(fullName);

var methodName = groups["method"].Value;
var method = bllType.GetMethod(methodName);
if (null != method)
{
string[] parameterValues = GetMethodParameterValues(context.Request, method);

var instance = Activator.CreateInstance(bllType);

var result = method.ReturnType == typeof(void) ? "{}" : method.Invoke(instance, parameterValues).ToString();
//以上Invoke省略了判断以及捕捉异常
context.Response.Write(result);
}
else
{
//返回不存在方法的提示
}
}
else
{
//url匹配不正确
}

有人可能会问为什么要重复SysBLL/SysBLL呢?其实可以省略其中的一个,但是条件是程序集必须要跟这个前缀一样才能省略.

  如果大家想要省略其中一次SysBLL,那么正则的匹配规则也要相应的调整一下,只要将(?<class>\w+.\w+)中的.\w+去掉即可.

  大致的实现流程就到这里了,我们已经将大部分的需求基本完成了,还有一些遗留的问题留给大家去完善啦,比如:调用的方法参数必须都是string类型,方法的返回值也必须要是string类型,反射的类不能是泛型类型的等等.

转自 https://www.cnblogs.com/ahl5esoft/archive/2012/06/27/2565496.html

 

C#实现简易ajax调用后台方法的更多相关文章

  1. asp.net如何在前台利用jquery Ajax调用后台方法

    一 :最近因为帮同事开发项目使用到了asp.net,而我又想实现Ajax异步请求....从网上查询了一下资料之后,原来在asp.net中利用Ajax调用后台方法同样很简单,为了便于自己以后查看,特将此 ...

  2. java 中使用ajax调用后台方法注意事项

    java 中使用ajax调用后台方法注意事项,后台方法一定要加@ResponseBody jQuery.validator.addMethod("checkRuleName",fu ...

  3. webform中 ajax调用后台方法(非webservice)

    方法一:通过创建一个没有内容的窗体 后台: public partial class Ajax_ShoppingCart : System.Web.UI.Page { bookdbDataContex ...

  4. Asp.net中JQuery、ajax调用后台方法总结

    通过上一篇文章实例的实现,整个过程当中学习到很多知识点,了解了Jquery.Ajax在asp.net中的运用,加以总结,其实原理都是一样的,理解了一种,其他的注意很少的区别就可以了.灵活运用: 1.有 ...

  5. jquery + ajax调用后台方法

    前台js: var parameter = ""; $.ajax({ type: "POST", //提交方式 url: "Default.aspx/ ...

  6. asp.net core 的 razor pages 如何使用ajax调用后台方法

    Razor 是一种允许您向网页中嵌入基于服务器的代码(Visual Basic 和 C#)的标记语法. 当网页被写入浏览器时,基于服务器的代码能够创建动态内容. 在网页加载时,服务器在向浏览器返回页面 ...

  7. asp.net ajax 调用后台方法

    js代码 <form id="form1" runat="server"> <script language=javascript type= ...

  8. asp.net core 通过ajax调用后台方法(非api)

    1.    在Startup.cs文件中添加:        services.AddMvc();            services.AddAntiforgery(o => o.Heade ...

  9. 前台JS(Jquery)调用后台方法 无刷新级联菜单示例

    前台用AJAX直接调用后台方法,老有人发帖提问,没事做个示例 下面是做的一个前台用JQUERY,AJAX调用后台方法做的无刷新级联菜单 http://www.dtan.so CasMenu.aspx页 ...

随机推荐

  1. angularJS 常用插件指令

    长时间没有登入博客园了,今天突然想了想,当初开这个的目的,其实就是为了记录你当下的一个状态和累计一些问题,所以记录这些还是很有意义,毕竟不是什么牛,靠脸又吃不饱的这个年代,需要留下一些东西给自己看也好 ...

  2. java中使用opencv

    Java + opencv学习:在Eclipse下配置基于Java的OpenCV开发环境 2016-04-08 17:43 6491人阅读 评论(0) 收藏 举报  分类: OpenCV学习(10)  ...

  3. Qt 5.5.0 Windows环境搭建

    1)訪问官方站点:http://www.qt.io/download-open-source/ 2)选择离线安装包 3)选择 Windows 离线安装包(32 位或 64 位都可用,Windows 6 ...

  4. 继承的文本框控件怎么响应EN_CHANGE等消息

    继承的文本框控件如何响应EN_CHANGE等消息?我从CEdit继承了一个CMyEdit类,想在这个类里填写它的一些消息.我在消息映射表里写的是MESSAGE_HANDLER(EN_CHANGE, O ...

  5. 基于EasyDarwin实现幼儿园监控类项目

    移动互联网越来越普及,幼儿园监控类的项目也越来越多,如何能够以最低的成本.最快的速度搭建一套幼儿园监控类的平台成了许多开发者的需求,那么我们今天就来简单探讨一下如何基于EasyDarwin实现一套幼儿 ...

  6. NET 并发编程

    场景并发调用API 1.简单封装httpclient public class CommonHelper { private static readonly HttpClient _httpClien ...

  7. java object monitor

    1 什么是java object monitor 每个java对象头中都有锁状态位标记.java中在使用synchronize同步的时候,肯定是涉及到某个对象的锁.因此,在考虑同步的时候,首先要想到是 ...

  8. spring4.2更好的应用事件

    1.基于注解驱动事件监听器:现在可以在一个Bean的方法上使用@EventListener注解来自动注册一个ApplicationListener来匹配方法签名. @Component public ...

  9. 【bzoj2809】dispatching

    这题的最优解法是可并堆,从上往下合并及删点,标准的O(nlogn)解法. 为了练习主席树,特用主席树写一发,可以按dfs序建立主席树,对每个子树进行查询. 总时间5232毫秒,要垫底了... 看来需要 ...

  10. win7 64位系统与Ubuntu14.04 64位系统双系统安装【转】

    本文转载自:http://blog.csdn.net/strugglepeach/article/details/51260886 Window 7 + Ubuntu 双系统安装   硬件: Thin ...