与webform平台上的各种实现方式比较(3)

public class PageBase : Page { private static Hashtable _ajaxTable = Hashtable.Synchronized(new Hashtable()); public override void ProcessRequest(HttpContext context) { HttpRequest request = context.Request; if (string.Compare(request.Headers["AjaxFlag"],"XHR",true) == 0) { InvokeMethod(request.Headers["MethodName"]); } base.ProcessRequest(context); } /// <summary> /// 反射执行函数 /// </summary> /// <param></param> private void InvokeMethod(string methodName) { if (string.IsNullOrEmpty(methodName)) { EndRequest("MethodName标记不能为空!"); } CacheMethodInfo targetInfo = TryGetMethodInfo(methodName); if (targetInfo == null) { EndRequest("找不到合适的方法调用!"); } try { object[] parameters = GetParameters(targetInfo.Parameters); string data = targetInfo.MethodInfo.Invoke(this, parameters) as string; EndRequest(data); } catch (FormatException) { EndRequest("参数类型匹配发生错误!"); } catch (InvalidCastException) { EndRequest("参数类型转换发生错误!"); } catch (ThreadAbortException) { } catch (Exception e) { EndRequest(e.Message); } } /// <summary> /// 获取函数元数据并缓存 /// </summary> /// <param></param> /// <returns></returns> private CacheMethodInfo TryGetMethodInfo(string methodName) { Type type = this.GetType().BaseType; string cacheKey = type.AssemblyQualifiedName; Dictionary<string, CacheMethodInfo> dic = _ajaxTable[cacheKey] as Dictionary<string, CacheMethodInfo>; if (dic == null) { dic = new Dictionary<string, CacheMethodInfo>(); MethodInfo[] methodInfos = (from m in type.GetMethods(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static) let ma = m.GetCustomAttributes(typeof(AjaxMethodAttribute), false) where ma.Length > 0 select m).ToArray(); foreach (var mi in methodInfos) { CacheMethodInfo cacheInfo = new CacheMethodInfo(); cacheInfo.MethodName = mi.Name; cacheInfo.MethodInfo = mi; cacheInfo.Parameters = mi.GetParameters(); dic.Add(mi.Name, cacheInfo); } _ajaxTable.Add(cacheKey, dic); } CacheMethodInfo targetInfo = null; dic.TryGetValue(methodName, out targetInfo); return targetInfo; } /// <summary> /// 获取函数参数 /// </summary> /// <param></param> /// <returns></returns> private object[] GetParameters(ParameterInfo[] parameterInfos) { if (parameterInfos == null || parameterInfos.Length <= 0) { return null; } HttpRequest request = this.Context.Request; NameValueCollection nvc = null; string requestType = request.RequestType; if (string.Compare("GET", requestType, true) == 0) { nvc = request.QueryString; } else { nvc = request.Form; } int length = parameterInfos.Length; object[] parameters = new object[length]; if (nvc == null || nvc.Count <= 0) { return parameters; } for (int i = 0; i < length; i++) { ParameterInfo pi = parameterInfos[i]; string[] values = nvc.GetValues(pi.Name); object value = null; if (values != null) { if (values.Length > 1) { value = String.Join(",", values); } else { value = values[0]; } } if (value == null) { continue; } parameters[i] = Convert.ChangeType(value, pi.ParameterType); } return parameters; } private void EndRequest(string msg) { HttpResponse response = this.Context.Response; response.Write(msg); response.End(); } }

  页面类:

public string GetData3(int i, double d, string str) { string[] datas = new string[] { i.ToString(), d.ToString(), str }; return "参数分别是:" + String.Join(",", datas); }

  前台代码:

function getData3(){ $.ajax({ headers:{"AjaxFlag":"XHR","MethodName":"GetData3"}, data:{"i":1,"d":"10.1a","str":"hehe"}, success:function(data){ $("#result").text(data); } }); }

五、总结

  上面的页面基类已经具备可以完成基本的功能,但它还不够好。主要有:

  1. 依附在页面基类。对于本来有页面基类的,无疑会变得更加复杂。我们希望把它独立开来,变成一个单独的组件。

  2. 效率问题。反射的效率是很低的,尤其在web这类应用程序上,更应该慎用。以动态执行函数为例,效率主要低在:a.根据字符串动态查找函数的过程。b.执行函数时,反射内部需要将参数打包成一个数组,再将参数解析到线程栈上;在调用前CLR还要检测参数的正确性,再判断有没有权限执行。上面的优化其实只优化了一半,也就是优化了查找的过程,而Invoke同样会有性能损失。当然,随着.net版本越高,反射的效率也会有所提升,但这种动态的东西,始终是用效率换取灵活性的。

  3.不能支持复杂参数。有时候参数比较多,函数参数一般会封装成一个对象类型。

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

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