聊城seo整站优化报价,网站建设与服务技能实训心得体会,wordpress 添加小工具,jsp做的个人网站小小目录: 为什么要写自己的Ajax后台框架 框架的简单设计说明 框架如何使用 框架使用效果图 框架的优缺点 框架源码下载1、为什么要写自己的Ajax后台框架 现在Ajax在web应用方面已经用的稀巴烂了#xff0c;如果你做一个网站没有用到ajax都不好意思拿出手… 小小目录: 为什么要写自己的Ajax后台框架 框架的简单设计说明 框架如何使用 框架使用效果图 框架的优缺点 框架源码下载 1、为什么要写自己的Ajax后台框架 现在Ajax在web应用方面已经用的稀巴烂了如果你做一个网站没有用到ajax都不好意思拿出手虽然面对ajax的潮流下在.net开放方向微软已经做了很多工作了比如推出了ajax的服务器端控件但是他不够灵活用的人多吗不多 在.Net环境下与ajax配合的几种情况主要是针对webform因为.net mvc你只要写action就可以将方法给发布出来实现ajax的调用 1.用ajax访问aspx页面直接在page_load中输出html代码并且End掉多余标签的输出但是他还要走生命周期一个好好的aspx页面只用这个功能怪怪的当然还可以直接在aspx.cs上面的方法上加上[webMethod]特性来标记ajax访问但是必须该方法为静态用起来也不是很爽。 2.用ajax访问ashx一般处理程序这个是在.net的ajax开发中一种常见明确推荐的方式他输出页面少不冗余代码调用灵活但是他通常一个ashx页面只提供一个功能但是市面上有可以通过switch方法的参数或者用委托或者反射的方法来实现一个ashx页面提供多个ajax访问的功能但是没发现这样也挺乱的吗我之前一直用这个慢慢的 慢慢的开始讨厌这种写好写法! 3.用ajax直接调用webservice服务这样的好处是在一个普通的webserive类中可以使用多个对外ajax访问点的发布用起来很灵活但是你一般的小网站为了ajax的访问还是部署webservice还是比较烦的吧 4.用ajax去调用wcf微软推出了wcf并且现在公认为他是一种可以替代webservice的新产品并且他还支持奖wcf部署在web服务器上以url形式发布当然了这样就可以用ajax来访问调用但是同上小网站小应用还要去弄wcf也是挺烦的一件事情 不知道大家发现没有第一二中方法其实终于还是访问了业务类里面的方法是否感觉ajax调ashxaspx有些多余还有第三四中方法其实可以看做业务类里面的方法但是需要发布才可以使用挺烦那有没有可能让ajax直接去访问cs类里面的方法呢 我就开始查资料看看网上别人的一些做法和看法,之前在.net方面有个叫做ajaxpro的dll可以实现cs发布成ajax但是感觉使用起来还是有点复杂就自己琢磨着自己能否开发一个.net的ajax后台框架在普通cs类的方法上面稍加修饰不改变方法原有功能但是能将方法发布出来 2、框架的简单设计说明 经过几点的奋战终于有了一个初步可以用的版本先贴上设计的类图 看了这个图是不是看上出还是比较繁琐?那接下来再来看下这个框架运行的泳道图应该就比较明了 他其实就分让相应的url进入指定的handlerfactory里面这个factory去指定调用相应的handler你可以看做ashx文件然后去解析地址栏的url得到具体的方法再去动态执行最后输出结果即可大致流程就是这样现在我来说一些细节 url的一些解析问题本次设计的url例如http://domain.com/classname/method.ajax?param...从url里面可以解析得到此次请求的class类名以及具体的method方法名当然所属的程序集是需要配置的好的这样就可以通过反射具体得到方法 如何得到方法由于得到的类名方法名都是字符串我们知道可以使用.Net里面的反射功能来实现通过字符串去调用相应的方法但是反射消耗的性能还是很大的所以我做了缓存在一个方法成功请求之后我就将该方法缓存起来以便下一次的时候不需要再反射直接调用缓存. View Code 1 #region 获取该方法2 3 if (_idictMethod.Keys.Contains(this.DictKey))4 {5 #region 存在缓存中 直接从缓存中取得6 //如果该方法被访问过 存在该字典中7 customMethodInfo _idictMethod[this.DictKey];8 //更新执行时间9 customMethodInfo.LastUpdateTime DateTime.Now;
10 //访问次数加1
11 customMethodInfo.Count;
12 //将调用后的信息反写进去
13 _idictMethod[this.DictKey] customMethodInfo;
14 #endregion
15 }
16 else {
17 #region 如果缓存中不存在 将会反射重新获取方法信息 并且记录缓存
18 customMethodInfo this.GetMethodBaseInfo();
19 if (customMethodInfo null)
20 {
21 throw new MethodNotFoundOrInvalidException(string.Format(没有找到方法{0}, this._methodPathInfo.MethodName));
22 }
23 else
24 {
25 #region 初始化方法的一些信息
26 //特性列表
27 customMethodInfo.AttrList ReflectionHelper.GetAttributesValidateAttr(customMethodInfo.Method);
28 //参数列表
29 customMethodInfo.ParamterInfos customMethodInfo.Method.GetParameters();
30 //返回值类型
31
32 customMethodInfo.RetureType customMethodInfo.Method.ReturnType;
33 //方法最后的更新时间
34 customMethodInfo.LastUpdateTime DateTime.Now;
35 //方法的执行次数
36 customMethodInfo.Count 1;
37 #endregion
38
39 #region 加了双重锁 防止死锁掉 将该方法加入缓存
40 //通过了特性的检测
41 if (!_idictMethod.Keys.Contains(this.DictKey))
42 {
43 lock (obj)
44 {
45 //防止在锁的时候 其他用户已经添加了键值
46 if (!_idictMethod.Keys.Contains(this.DictKey))
47 {
48 //将 此方法的信息记录到静态字典中 以便下次从内存中调用
49 _idictMethod.Add(this.DictKey, customMethodInfo);
50 }
51 }
52 }
53 #endregion
54
55 }
56 #endregion
57 }
58 #endregion 并且为了尽量少反射减少用户请求时间在第一次程序运行的时候我就将可能为标记ajax的方法给预缓存了起来用静态构造方法可以实现该功能该构造方法仅仅在第一次使用该类的时候运行并且只运行一次 View Code 1 #region 初始化缓存2 /// summary3 /// 初始化缓存4 /// /summary5 private static void InitCache()6 {7 ICollection assemblies BuildManager.GetReferencedAssemblies();8 9 foreach (Assembly assembly in assemblies)
10 {
11
12 if (UrlConfig.ASSEMBLY.Equals(assembly))
13 {
14 //如果在指定的ajax的业务的程序集中
15
16 //添加到程序集的缓存中
17 if (!_idictAssemby.Keys.Contains(GetAssemblyName(assembly)))
18 {
19 _idictAssemby.Add(GetAssemblyName(assembly), assembly);
20 }
21
22 try
23 {
24 foreach (Type t in assembly.GetExportedTypes())
25 {
26 Type[] allInterface t.GetInterfaces();
27 foreach (Type interfaceName in allInterface)
28 {
29 if (IAjax.Equals(interfaceName.Name))
30 {
31 // 该类有IAjax的接口 则默认添加进缓存 添加到类的缓存中
32 if (!_idictClass.Keys.Contains(t.FullName))
33 {
34 _idictClass.Add(t.FullName, t);
35 }
36
37 }
38 }
39 }
40 }
41 catch { }
42 }
43
44
45 }
46
47 //针对方法添加缓存
48 foreach (string className in _idictClass.Keys)
49 {
50 foreach (MethodInfo methodInfo in _idictClass[className].GetMethods(_bindingAttr))
51 {
52 try
53 {
54 ListValidateAttr attrList ReflectionHelper.GetAttributesValidateAttr(methodInfo);
55
56 //有标志的WebMethodAttr属性 添加进方法的缓存
57 WebMethodAttr webMethodAttr attrList.Find(x x is WebMethodAttr) as WebMethodAttr;
58 if (webMethodAttr null)
59 {
60 //没有该特性
61 continue;
62 }
63 CustomMethodInfo customMethonfInfo new CustomMethodInfo()
64 {
65 AttrList attrList,
66 Count 0,
67 LastUpdateTime DateTime.Now,
68 Method methodInfo,
69 RetureType methodInfo.ReturnType,
70 ParamterInfos methodInfo.GetParameters(),
71 Instance Activator.CreateInstance(_idictClass[className]),
72 Assembly _idictClass[className].Assembly
73
74 };
75 //添加进方法的缓存里面去
76 if (!_idictMethod.Keys.Contains(className.methodInfo.Name))
77 {
78 _idictMethod.Add(className . methodInfo.Name, customMethonfInfo);
79 }
80
81 }catch{}
82
83
84 }
85 }
86 }
87
88 /// summary
89 /// 得到程序集的名称 不带版本信息的
90 /// /summary
91 /// param nameassembly/param
92 /// returns/returns
93 private static string GetAssemblyName(Assembly assembly)
94 {
95 return assembly.FullName.Split(,)[0];
96 }
97 #endregion 这样就可以尽可能得降低反射因为消耗的性能而带来产生的效率问题 本框架在方法特性上作了扩展以标记特性的方式可以对ajax方法做一些操作比如参数的验证缓存的输出等并且该特性都是很容易扩展的只要继承ValidateAttr类即可实现接口的扩展为以后比如用户权限认证访问量限制等需要提供很好的解决方案 View Code 1 #region 检查方法的特性 未完善2 /// summary3 /// 检查方法的特性 未完善4 /// 现在主要是请求权限的验证 参数的验证5 /// /summary6 /// param namemethodInfo/param7 /// param nameerrMsg验证失败时带出的消息/param8 /// returns/returns9 private bool CheckAttribute(ListValidateAttr attrList)
10 {
11 bool ret true;
12 if (attrList.Count 0)
13 {
14 foreach (ValidateAttr attr in attrList)
15 {
16 attr.CurrentHttpRequest this._httpRequestDescription;
17 #region 判断此特性是否能通过验证
18 if (!attr.IsValidate())
19 {
20 //特性的验证规则失败
21 ret false;
22 break;
23 }
24 #endregion
25 }
26 }
27 else
28 {
29 throw new MethodNotFoundOrInvalidException(此方法并不是网络方法无法直接访问);
30 }
31
32 return ret;
33 }
34 #endregion 在不可或缺的参数验证特性上面简单的使用了策略模式可以低耦合的实现其他一些参数类型扩展 View Code 最后在页面输出方面使用了一个简单的输出帮助以以AjaxResult结果寄存类和json的一个序列化类就行输出 View Code /// summary/// /// /summary/// param namereturnValue返回值/param/// param namereturnType返回类型/param/// returns返回字符串/returnspublic static string GetResponseString(object returnValue,Type returnType){string ret string.Empty;try{if (returnType.IsSampleType()){//返回的是简单类型AjaxResult ajaxResult new AjaxResult(){Flag 1,Data Convert.ToString(returnValue)};ret ajaxResult.ToString();}else{ret JsonConvert.SerializeObject(returnValue);}}catch (Exception ex){//遇到异常AjaxResult errResult new AjaxResult(){Flag 0,ErrorMsg ex.Message};ret errResult.ToString();}return ret;}/// summary/// 返回错误/// /summary/// param nameerrorMessge/param/// returns/returnspublic static string ResponseError(string errorMessge){//返回错误AjaxResult errResult new AjaxResult(){Flag 0,ErrorMsg errorMessge};return errResult.ToString();} 3、框架如何使用 本框架暂时命名为AjaxFramework所以你在使用本框架时只需要引用该dll然后在webconfig里面针对不同的IIS版本配置好相应的HttpHandler View Code httpHandlers
!--针对IIS6 再这里配置handler 以支持ajax后缀的扩展--add verb* path*.ajax validatetrue typeAjaxFramework.AjaxHandlerFactory,AjaxFramework /
/httpHandlershandlers
!--针对IIS7 再这里配置handler 以支持ajax后缀的扩展--add nameajaxhandler verb* preConditionintegratedMode path*.ajax typeAjaxFramework.AjaxHandlerFactory,AjaxFramework /
/handlers 这里的.ajax后缀根据你的需求修改比如你可以修改成.json,以后以相应的后缀访问就可以了 再配置好你需要公布的命名空间 View Code appSettings!--在此处配置ajax后台框架所需映射的项目--add keyAjaxFramewok valueTestBLL//appSettings 至此配置已经完成是不是还算简单 用法就如下了 View Code 这标明TestBLL空间里面的Data类里面的Add方法被发布了出来是不是很简单只需要添加相应的特性即可完成发布网络方法的操作 然后你可以用http://domain.com/data/add.ajax?a4b6.787的url形式就行访问了 4、 框架使用效果图 先来看一下上面一个章节里面那个发布方法的效果图 我们来看下用Get方式去访问Post标记方法的情况 View Code /// summary/// 这个方法只有Post请求才可以/// /summary/// returns/returns[WebMethodAttr(RequestType.Post)]public string Get_Pat(){return pat;} 我们来看下普通类型返回的情况 View Code /// summary/// 返回普通的字符串 会加上一个json的外壳/// /summary/// returns/returns[WebMethodAttr(RequestType.Get)][OutputCacheAttr(20)]public string Get_Pat2(){return pat DateTime.Now.ToString(yyyyMMddHHmmssfff);} 但是如果返回的是DataTable会怎么样呢 View Code /// summary/// 返回DataTable的数据/// /summary/// returns/returns[WebMethodAttr(RequestType.Get)]public DataTable Get_Data(){DataTable dt new DataTable(dt);dt.Columns.Add(id);dt.Columns.Add(name);DataRow row dt.NewRow();row[id] 1;row[name] tom;dt.Rows.Add(row);DataRow row2 dt.NewRow();row2[id] 2;row2[name] peter;dt.Rows.Add(row2);return dt;} 那么如果方法的参数是实体类型我们该如何传呢 View Code /// summary/// 这个方法是用来测试传实体的/// /summary/// param nameuser/param/// returns/returns[WebMethodAttr(RequestType.Get)]public User Insert_User(User user){return user;} 估计方法配图大家应该看的很明白了吧 在这里提一下由于现在ajax的请求返回类型基本都是json格式所以本框架暂时只支持json格式 5、框架的优缺点 先来说优点吧 1你以后在使用ajax的时候不需要再加各种ashxaspx页面加上相应的特性即可将你业务层里面的方法给发布出来 2利用特性扩展这一特点可以很方便的满足你其他的要求 3运用了各种方式的缓存效率应该不会将到哪里去 3整体框架还算简单运行思路明了相对wcfwebservice这些复杂的框架以后出错可以手动调试源码 估计缺点也有很多 1由于是通过反射来运行方法的某些时候效率可能会不怎么高 2在参数动态赋值模块对于其他的一些参数可能会有问题 3:发布方法无法重载 4只是刚刚写出来没有投入到实际项目中可用性还有待商榷 这个框架可以用哪里 一般的小OAERP个人博客站小的CMS站普通企业站个人觉得这个框架还是可以应付的如果需要在其他类型的网站上使用你就自己看着办吧 6、源码下载 我厚着脸皮的发到了Github上面去点我去Github下载AjaxFrameworkjson类库在lib文件夹中可能需要重新引用一遍希望有兴趣的同学可以加入进来一些开发哦有问题留言吧很期待您的指导转载于:https://www.cnblogs.com/yyl8781697/archive/2013/05/09/ajaxframework.html