博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
反射+特性打造简洁的AJAX调用
阅读量:5037 次
发布时间:2019-06-12

本文共 8012 字,大约阅读时间需要 26 分钟。

(声明:本文转自)

这里我要实现类似AjaxPro组件调用效果的功能,先看看AjaxPro在CS文件中的代码是怎么写的。

//在后台写的有参方法[AjaxPro.AjaxMethod]public string getString(string str){return str + "Say: hello my friends";}

前台页面的调用方式

function Button4_onclick() {var str=document.getElementByIdx_x("<%=TextBox1.ClientID %>").value;WebUI._Default.getString(str,getStringCallBack);}

这样的调用代码相当于在客户端直接执行了服务器端代码,然后取到执行结果,是不是有点意思,接下来我们就来自己把这类似的功能实现一把。

不过在实现之前你最好对反射和特性的基本运用有一定的了解,马上进入正题。

 

首先我们来理一下实现的思路

1.定义能应用在方法上的Ajax标识特性,因为并不是Page对象的所有方法都需要公开被调用,可以用特性做一个标记,可以通过MethodAliasName属性为方法设置一个方法别名,这样做的目的主要是为了安全和AJAX调用代码更简洁。

using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace AjaxInvokeDemo.Ajax{    [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]    public class AjaxMethodAttribute : Attribute    {        ///         /// 设置ajax调用时的方法别名        ///         public string MethodAliasName        {            get;            set;        }    }}

 

2.定义页面基类,在里面实现一些公用的逻辑。比如获取要执行的方法的名称以及方法的参数,并通过反射对方法进行调用。具体还是看代码吧,可能更清楚一点。

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Runtime;using System.Reflection;using System.Collections.Specialized;namespace ConfigDemo.Ajax{    public abstract class AjaxPage
: System.Web.UI.Page { private static readonly string AjaxMethodCacheName = "AjaxMethods"; private string pageName = typeof(T).Name; private Type pageType = typeof(T); protected override void OnPreInit(EventArgs e) { if (Cache[AjaxMethodCacheName] == null) { AjaxMethods = AjaxHelper.GetAjaxMethods
(); Cache[AjaxMethodCacheName] = AjaxMethods; } else { AjaxMethods = Cache[AjaxMethodCacheName] as Dictionary
; } base.OnPreInit(e); } protected override void OnLoad(EventArgs e) { ExecuteAction(); base.OnLoad(e); } public Dictionary
AjaxMethods { get; set; } ///
/// Action名称或者别名 /// public string CurrentActionName { get { if (!string.IsNullOrEmpty(HttpContext.Current.Request["action"])) { return HttpContext.Current.Request["action"]; } throw new Exception("调用时必须指定Action参数.."); } } ///
/// 传递的参数集合 /// public object[] CurrentParams { //一般的调用URL格式为 http://xxxxx/yyy.aspx?action=method&id=a001 ... get { NameValueCollection NVs = HttpContext.Current.Request.QueryString; object[] objs = new object[NVs.Count-1]; //这里将action参数排除在外 for(int i =1;i
/// 最终要执行的Page的方法的真实名称 /// public string CurrentAjaxMethodName { get; set; } public void ExecuteAction() { if (!AjaxMethods.ContainsKey(CurrentActionName) && !AjaxMethods.ContainsValue(CurrentActionName)) { throw new Exception("调用的方法不存在或者未被公开为Ajax方法.."); } //没有为Ajax方法指定别名 if (AjaxMethods.ContainsKey(CurrentActionName) && AjaxMethods[CurrentActionName] == CurrentActionName) { CurrentAjaxMethodName = CurrentActionName; } else { //为Ajax方法指定了别名 CurrentAjaxMethodName = AjaxMethods.First
>(x => x.Value == CurrentActionName).Key; } MethodInfo method = pageType.GetMethod(CurrentAjaxMethodName); if (method != null) { object PageObj = GetPageInstance(); method.Invoke(PageObj, CurrentParams); } } public object GetPageInstance() { if (Cache[pageName] == null) { object PageObj = Activator.CreateInstance(pageType); return Cache[pageName] = PageObj; } else { return Cache[pageName] as object; } } }}

 

3.为了获取被标识为AjaxMethod的方法集合,这里专门用一个AjaxHelper类实现。

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Reflection;namespace ConfigDemo.Ajax{    public class AjaxHelper    {        ///         /// 获取指定Page对象中标记为Ajax的方法集合        ///         /// 
/// ///
public static Dictionary
GetAjaxMethods
() { Dictionary
ajaxMethods = new Dictionary
(); AjaxMethodAttribute ajaxMethodAttribute = null; //方法别名 string methodAliasName = string.Empty; Type t = typeof(T); MethodInfo[] methods = t.GetMethods(); foreach (MethodInfo method in methods) { object[] attributes = method.GetCustomAttributes(typeof(AjaxMethodAttribute), false); if (attributes != null && attributes.Length > 0) { ajaxMethodAttribute = (AjaxMethodAttribute)attributes[0]; //如果没有为ajax调用方法设置别名则用方法本身的名称 methodAliasName = string.IsNullOrEmpty(ajaxMethodAttribute.MethodAliasName) == true ? method.Name : ajaxMethodAttribute.MethodAliasName; ajaxMethods.Add(method.Name, methodAliasName); } } return ajaxMethods; } }}

 

4.基础框架搭建完毕,看看怎么使用

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.UI;using System.Web.UI.WebControls;using System.Reflection;using System.Text;namespace AjaxInvokeDemo.Ajax{    public partial class Index : AjaxPage
{ protected void Page_Load(object sender, EventArgs e) { } [AjaxMethod] public void GetPerson(string id) { List
ps = new List
(); ps.Add(new Person { Id = "a001", Name = "abc", Sex = "男", Age = 20 }); ps.Add(new Person { Id = "a002", Name = "xyz", Sex = "女", Age = 18 }); ps.Add(new Person { Id = "a003", Name = "zzzz", Sex = "男", Age = 28 }); ps.Add(new Person { Id = "a004", Name = "yyy", Sex = "男", Age = 21 }); StringBuilder builder = new StringBuilder(); Person person = ps.Find(p => p.Id == id); if (person != null) { //http://htmltextwriterutil.codeplex.com/ 这是htmltextwriter工具的下载地址,一款拼字符串的好工具 builder.Append("
    "); builder.AppendFormat("
  • 编号:{0}
  • ",person.Id); builder.AppendFormat("
  • 姓名:{0}
  • ", person.Name); builder.AppendFormat("
  • 性别:{0}
  • ", person.Sex); builder.AppendFormat("
  • 年龄:{0}
  • ", person.Age); builder.Append("
"); } HttpContext.Current.Response.Write(builder.ToString()); HttpContext.Current.Response.End(); } } public class Person { public string Id { get; set; } public string Name { get; set; } public string Sex { get; set; } public int Age { get; set; } }}

这里的使用有两个要点,一是页面要继承自AjaxPage<T>泛型类,第二是在要被客户端调用的方法上加上[AjaxMethod]特性,一切就这么简单。。

 

5.客户端调用

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="AjaxTest.aspx.cs" Inherits="AjaxInvokeDemo.Ajax.AjaxTest" %>                    
用户ID:

 至此,调用完毕。。。

 

 

转载于:https://www.cnblogs.com/nikyxxx/archive/2012/08/26/2657184.html

你可能感兴趣的文章
HTML5实践 -- iPhone Safari Viewport Scaling Bug
查看>>
一位数据挖掘成功人士 给 数据挖掘在读研究生 的建议
查看>>
Python3.6.0安装
查看>>
hdu1049
查看>>
H5项目常见问题及注意事项
查看>>
索尼(SONY) SVE1512S7C 把WIN8降成WIN7图文教程
查看>>
时间模块 && time datetime
查看>>
jquery自动生成二维码
查看>>
spring回滚数据
查看>>
新浪分享API应用的开发
查看>>
美国专利
查看>>
【JavaScript】Write和Writeln的区别
查看>>
百度编辑器图片在线流量返回url改动
查看>>
我对你的期望有点过了
查看>>
微信小程序wx:key以及wx:key=" *this"详解:
查看>>
下拉框比较符
查看>>
2.2.5 因子的使用
查看>>
css选择器
查看>>
photoplus
查看>>
Python 拓展之推导式
查看>>