在当前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. C语言宏定义时#(井号)和##(双井号)作用

    #的功能是将其后面的宏参数进行字符串化操作(Stringfication),简单说就是在对它所引用的宏变量 通过替换后在其左右各加上一个双引号. #define example(instr) prin ...

  2. 图像滤镜艺术---PS图层混合模式之明度模式

    本文将介绍PS图层混合模式中比較复杂 的"明度"模式的算法原理及代码实现内容. 说到PS的图层混合模式,计算公式都有,详细代码实现也能找到,可是,都没有完整介绍全部图层混合模式的代 ...

  3. 用JS写九九乘法表

    本来JS部分觉得就不是很好,结果经过一个寒假,在家的日子过的太舒适,基本把学的都快忘干净了,今天老师一说九九乘法表,除了脑子里浮现出要满足的条件,其他的都不记得了,赶快整理了一下: <scrip ...

  4. 基于EasyIPCamera实现的数字网络摄像机IPCamera的模拟器IPC RTSP Simulator

    还记得去年在北京安博会上,看到一些厂家的展示台上,各种船舶.公路.车辆的高清视频直播,好奇这些数据是怎么接到现场的,现场成百上千家展台,不可能有那么大的带宽供应,细想数据肯定不是实时的,果然,盯着看了 ...

  5. 开源G711(PCMA、PCMU)/G726转AAC项目EasyAACEncoder

    EasyDarwin开源社区整理了一份G711(PCMA.PCMU)/G726转AAC的转码库,支持Windows/Linux跨平台使用,将安防标准的G711转成移动互联网常用的AAC格式,希望能给大 ...

  6. vue http 请求

    https://github.com/vuejs/awesome-vue#http-requests vue-resource - npm https://www.npmjs.com/package/ ...

  7. 虚拟机linux安装mysql

    安装mysql时需要的全套安装包 mysql-5.1.73-3.el6_5.i686.rpm mysql-libs-5.1.73-3.el6_5.i686.rpm mysql-server-5.1.7 ...

  8. BNUOJ 34978 汉诺塔 (概率dp)

    题目分析:对于 i 个盘 , 须要移动多少步,取决于最大的盘子在哪个杆上.在C杆上,则最大的盘不须要移动,由于初始状态一定是满足盘由下到上盘子依次变小的,仅仅须要移动i - 1个盘.假设在A杆上,则首 ...

  9. 不懂不能装懂--邮箱后缀“inc”的含义

    之前实习的公司,邮箱域名是XXX@XXX-inc.com 再之前,投递简历了或者关注某个公司的一些信息或者和这些公司的人邮件联系是也发现有这个inc的后缀,一直不明白,今天觉得自己找到答案了,不怕丢人 ...

  10. Android Weekly Notes Issue #246

    Android Weekly Issue #246 February 26th, 2017 Android Weekly Issue #246 本期内容包括: RecyclerView上的Shared ...