asp.net ashx处理程序中switch case的替代方案总结
2019-08-01 22:04
1101 查看
目录
在开发 asp.net 项目中,通常使用一般处理程序(ashx)处理前端发送过来的请求,因为一个handler会处理多个请求,故ajax请求中一般都会加一个action的参数,在handler里根据这个action做相应的处理或返回相应的数据,这里大多数人都会想到用switch...case做判断,一开始我也是用的switch,但渐渐地发现,每个case不像一个代码块,不能为其中的变量提供一个独立的作用域!而且,如果case的情况比较多的话,代码看上去也比较臃肿难维护;
那如何替换掉switch...case呢,我想到了如下两个方案:
1、用委托字典代替switch...case;
首先在handler里声明一个私有的静态委托字典,key为action字符串,value为Func委托;然后把action和对应的方法添加到字典中即可;
完整示例代码:
namespace WebApplication1 { public class Handler1 : IHttpHandler { static Dictionary<string, Action<HttpContext>> MapActions = new Dictionary<string, Action<HttpContext>>(StringComparer.OrdinalIgnoreCase) { {"Add", Add}, {"Sub", Sub} }; public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; try { var action = context.Request["Action"]; if (string.IsNullOrEmpty(action)) { context.Response.StatusCode = (int) HttpStatusCode.BadRequest; } if (MapActions.ContainsKey(action)) { var actionFun = MapActions[action]; if (actionFun != null) { actionFun(context); //或 //actionFun.Invoke(context); } else { context.Response.StatusCode = (int) HttpStatusCode.NotImplemented; } } else { context.Response.StatusCode = (int) HttpStatusCode.NotFound; } } catch (Exception e) { context.Response.StatusCode = (int) HttpStatusCode.InternalServerError; } finally { context.Response.End(); } } public static void Add(HttpContext context) { int num1 = int.Parse(context.Request["Num1"]); int num2 = int.Parse(context.Request["Num2"]); int result = num1 + num2; context.Response.Write(result); } public static void Sub(HttpContext context) { int num1 = int.Parse(context.Request["Num1"]); int num2 = int.Parse(context.Request["Num2"]); int result = num1 - num2; context.Response.Write(result); } public bool IsReusable { get { return false; } } } }
2、利用反射替代switch...case;
利用反射,将action的值与具体的方法对应上;
完整示例代码:
namespace WebApplication1 { public class Handler2 : IHttpHandler { static readonly Type[] SearchParamType = new[] { typeof(HttpContext) }; public void ProcessRequest(HttpContext context) { var result = ActionInvoke(context); context.Response.ContentType = "text/plain"; context.Response.Write(result); } private object ActionInvoke(HttpContext ctx) { var actionFun = this.GetType().GetMethod("ProcessAction_" + ctx.Request["action"] ?? "", BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public, null, SearchParamType, null); if (null == actionFun) { return "UnknowAction"; } return actionFun.Invoke(this, new[] { ctx }); } public int ProcessAction_Add(HttpContext context) { int num1 = int.Parse(context.Request["Num1"]); int num2 = int.Parse(context.Request["Num2"]); int result = num1 + num2; return result; } public int ProcessAction_Sub(HttpContext context) { int num1 = int.Parse(context.Request["Num1"]); int num2 = int.Parse(context.Request["Num2"]); int result = num1 - num2; return result; } public bool IsReusable { get { return false; } } } }
3、比较两种方案
反射会造成一定的性能损耗;所以使用委托字典方案更加靠谱;
4、其他方案
可以使用设计模式实现,比如工厂模式,状态模式,中介模式等,但用在上述这个场景,那么就有杀鸡用牛刀的 感觉了;
5、说明
在简单的逻辑中,case分支少,很少扩展,那么应该用switch语句,因为简单明了,易于阅读。
如果在复杂的逻辑中,复杂而且混乱的case,而且经常扩展什么的,就应该用委托和反射,使用缓存机制。
6、参考
重构:switch语句改成策略模式还是状态模式:https://www.geek-share.com/detail/2673199521.html
中介模式: https://www.geek-share.com/detail/2628401481.html
相关文章推荐
- Android调用asp.net编写的*.ashx(一般处理程序)获取数据
- asp.net 一般处理程序Handler.ashx应用实例
- ASP.NET知识总结(一般处理程序动态处理图片(验证码、水印、缩略图))
- ASP.NET一般处理程序(.ashx.cs)中使用Session的问题
- ASP.NET的ASHX一般处理程序中Session为null且不能赋值
- ASP.NET ASHX 一般处理程序教程
- ASP.NET ASHX 一般处理程序教程
- Asp.net 一般处理程序.ashx中对Session的操作
- Asp.net jQuery与ashx 安全性问题 (一般处理程序的安全问题) ashx 安全
- ASP.NET-C# Post 一般处理程序(ashx)并得到返回值
- 最近学习asp.net一般处理程序(.ashx)
- asp.net .ashx一般处理程序中使用Session
- asp.net- ajax简单入门使用方法,通过一般处理程序ashx进行处理
- ASP.net的HTTP处理程序(ASHX)提取dll内嵌资源图片
- ASP.NET ASHX 一般处理程序教程
- ASP.NET ----ashx一般处理程序
- asp.net 登陆后在ashx处理程序中获取不到Session
- asp.net 一般处理程序 .ashx 处理各种验证码 一维码 二维码
- ASP.NET 使用一般处理程序.ashx进行 Excel下载
- ASP.NET运行机制之一般处理程序(ashx)