编写轻量ajax组件第三篇实现(5)

  在执行委托前,我们需要先从请求获取参数,映射到方法。参数可以是简单的类型,如 string Test(int i,int j); 也可以是一个对象,如 string Test(User user); 如果是 string Test(User user1, User user2) 也行,提交参数时只需要加上 user1或 user2 前缀即可,例如 user1.Name,user2.Name。这里没有支持更多的匹配方式,像mvc,它还支持嵌套类型等等,这些可以自己去实现。如果参数是一个对象,我们可能需要为它的字段进行赋值,也可能为它的属性进行赋值。这里我们定义一个DataMember,用来表示字段或属性的父类。如:

internal abstract class DataMember { public abstract string Name { get; } public abstract Type MemberType { get; } public abstract void SetValue(object instance,object value); public abstract object GetValue(object instance); }

  接着定义属性类型PropertyMember和字段类型FieldMember,分别继承了DataMember。

  PropertyMember定义:

internal class PropertyMember : DataMember { private PropertyInfo property; public PropertyMember(PropertyInfo property) { if (property == null) { throw new ArgumentNullException("property"); } this.property = property; } public override void SetValue(object instance, object value) { if (instance == null) { throw new ArgumentNullException("instance"); } this.property.SetValue(instance, value, null); } public override object GetValue(object instance) { if (instance == null) { throw new ArgumentNullException("instance"); } return this.property.GetValue(instance,null); } public override string Name { get { return this.property.Name; } } public override Type MemberType { get { return this.property.PropertyType; } } }

  FieldMember定义:

internal class FieldMember : DataMember { private FieldInfo field; public FieldMember(FieldInfo field) { if (field == null) { throw new ArgumentNullException("field"); } this.field = field; } public override void SetValue(object instance, object value) { if (instance == null) { throw new ArgumentNullException("instance"); } this.field.SetValue(instance, value); } public override object GetValue(object instance) { if (instance == null) { throw new ArgumentNullException("instance"); } return this.field.GetValue(instance); } public override string Name { get { return this.field.Name;} } public override Type MemberType { get { return this.field.FieldType; } } }

  定义一个DataMemberManager,用来遍历Type,获取所有字段和属性的,实现如下:

internal static class DataMemberManager { /// <summary> /// 获取实例字段/属性集合 /// </summary> /// <param>类型</param> /// <returns></returns> public static List<DataMember> GetDataMember(Type type) { if (type == null) { throw new ArgumentNullException("type"); } IEnumerable<PropertyMember> propertyMembers = from property in type.GetProperties(BindingFlags.Instance | BindingFlags.Public) select new PropertyMember(property); IEnumerable<FieldMember> fieldMembers = from field in type.GetFields(BindingFlags.Instance | BindingFlags.Public) select new FieldMember(field); List<DataMember> members = new List<DataMember>(); foreach(var property in propertyMembers) { members.Add(property); } foreach (var field in fieldMembers) { members.Add(field); } return members; } }

  在前面我们定义的Handler的ProcessRequest方法中,我们调用了Executor.Execute,该方法用于执行委托,实现如下:

/// <summary> /// 核心函数,执行Handler的方法 /// </summary> /// <param>页面对象</param> /// <param>请求上下文</param> /// <param>缓存方法原数据</param> internal static void Execute(Page page, HttpContext context, CacheMethodInfo methodInfo) { if (page == null) { throw new ArgumentNullException("page"); } try { if (methodInfo != null) { HttpRequest request = context.Request; object[] parameters = GetParametersFromRequest(request, methodInfo.Parameters); object data = methodInfo.Func(page, parameters); int serverCache = methodInfo.AjaxMethodAttribute.ServerCache; if (serverCache > 0) { CacheHelper.Insert(context, methodInfo.AjaxMethodAttribute.ServerCache, data); } EndCurrentRequest(context, data, methodInfo.AjaxMethodAttribute.OutputCache); } else { EndCurrentRequest(context, "找不到合适的Ajax方法!"); } } catch (FormatException) { EndCurrentRequest(context, "调用方法匹配到无效的参数!"); } catch (InvalidCastException) { EndCurrentRequest(context, "参数转换出错!"); } catch (System.Threading.ThreadAbortException) { //do nothing } catch (Exception ex) { EndCurrentRequest(context, ex.Message); } }

  CacheMethodInfo我们已经获得了,现在只要获得参数我们就可以执行方法。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wjppjy.html