asp.net ashx处理程序中switch case的替代方案总结
在开发 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://blog.csdn.net/qq_21381465/article/details/51298808
中介模式: https://www.cnblogs.com/insus/p/4134383.html
asp.net ashx处理程序中switch case的替代方案总结的更多相关文章
- Javascript 中 switch case 等于 (== )还是 恒等于(===)?
Javascript 中 switch case 等于 (== )还是 恒等于(===)? 可以测试一下以下代码,这个 case 中是 等于(==)还是恒等于(===) <script> ...
- python中Switch/Case实现
学习Python过程中,发现没有switch-case,过去写C习惯用Switch/Case语句,官方文档说通过if-elif实现.所以不妨自己来实现Switch/Case功能. 方法一 通过字典实现 ...
- Python里如何实现C中switch...case的功能
python没有switch case 不过可以通过建立字典实现类似的功能 例子:根据输入的年月日,判断是该年中的第几天 y = int(input('请输入年:')) m = int(input(' ...
- asp.net 登陆后在ashx处理程序中获取不到Session
登录后存储Session,另一个页面Ajax请求 ashx页面,发现无法获取到Session,Session is NULL 使用“IReadOnlySessionState”这个接口就可以
- js中switch/case分支的值可以是变量或表达式
在一些高级语言如C#中,switch分支的值只能是常量,而js中可以是变量或表达式: <!DOCTYPE html> <html lang="en"> &l ...
- thymeleaf中switch case多出一个空行
以下是<thymeleaf3.0.5中文参考手册.pdf>中的代码,官方代码没有具体去查询. <div th:switch="${user.role}"> ...
- C# 中Switch case 返回不止用break
Switch(temp) { case "A": //跳出循环 break; case "B": //返回值 return var; case "C& ...
- 在ashx处理程序中,如果返回json串数据?
可以通过一下代码: using System.Collections.Generic;using System.Web.Script.Serialization; SortedDictionary&l ...
- 简谈switch case
工作中从buff里截取了一个字符串,然后和配置文件中的字符串名字对比 ,如果一样,处理,不一样,elseif 再判断,再处理! switch(){case : case :...... }先说语法,再 ...
随机推荐
- 从0到1构建网易云信IM私有化
本文来源于MOT技术管理课堂杭州站演讲实录,全文 2410 字,阅读约需 5分钟.网易云信资深研发工程师张翱从私有化面临的问题及需求说起,分享了网易云信IM私有化的解决方案和具体实践. 想要阅读更多技 ...
- 基于 SpringBoot 的 FileService
fileservice file upload download 1.支持多种存储服务器上传.下载 2.支持大文件切片上传 3.存储记录信息使用 redis记录, 文件id可用于与业务数据库关联 4. ...
- 简单的 自动生成 二维码 PHP 方法
方法一:<style type="text/css">.eweima{ width:200px; height:200px; margin:auto;}</ ...
- DFS(二):骑士游历问题
在国际象棋的棋盘(8行×8列)上放置一个马,按照“马走日字”的规则,马要遍历棋盘,即到达棋盘上的每一格,并且每格只到达一次.例如,下图给出了骑士从坐标(1,5)出发,游历棋盘的一种可能情况. [例1] ...
- HDU 6019:MG loves gold(暴力set)
http://acm.hdu.edu.cn/showproblem.php?pid=6019 题意:给出n个颜色的物品,你每次取只能取连续的不同颜色的物品,问最少要取多少次. 思路:从头往后扫,用se ...
- Azkaban 3.73.1 使用简介
本文上接<Azkaban 3.73.1 集群搭建(Multiple Executor)>,对Azkaban的使用做简单说明 目录 目录 简介 1. 登录 2. 创建工程 3. 创建job ...
- 大规模SDN云计算数据中心组网的架构设计
本文首先分析了在大规模SDN数据中心组网中遇到的问题.一方面Underlay底层组网规模受限于设备实际的转发能力和端口密度,单一Spine-leaf的Fabric架构无法满足大规模组网的需求:另一方面 ...
- Java设计模式学习笔记(二) 简单工厂模式
前言 本篇是设计模式学习笔记的其中一篇文章,如对其他模式有兴趣,可从该地址查找设计模式学习笔记汇总地址 正文开始... 1. 简介 简单工厂模式不属于GoF23中设计模式之一,但在软件开发中应用也较为 ...
- 和朱晔一起复习Java并发(三):锁(含锁性能测试)
这个专题我发现怎么慢慢演化为性能测试了,遇到任何东西我就忍不住去测一把.本文我们会大概看一下各种锁数据结构的简单用法,顺便也会来比拼一下性能. 各种并发锁 首先,我们定一个抽象基类,用于各种锁测试的一 ...
- MTSC2019第五届移动互联网测试开发大会PPT下载
关注公众号「软件测试大本营」后台回复「MTSC」或「测试开发大会」即可获取云盘下载地址及提取码. 注:PPT文件版权归相关撰写人所有,仅供学习交流,请勿用于任何商业用途,谢谢 前不久在北京举办了第五届 ...