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 :...... }先说语法,再 ...
随机推荐
- memcached分布式一致性哈希算法
<span style="font-family: FangSong_GB2312; background-color: rgb(255, 255, 255);">如果 ...
- 基于STM32之UART串口通信协议(一)详解
一.前言 1.简介 写的这篇博客,是为了简单讲解一下UART通信协议,以及UART能够实现的一些功能,还有有关使用STM32CubeMX来配置芯片的一些操作,在后面我会以我使用的STM32F429开发 ...
- kettle —— 从 oracle 到 oracle的坑
公司有个项目,是使用kettle从oracle上统计,再将结果跟oracle中目标表进行对比更新.接手后,走了一些弯路,中间各种尝试都不尽如人意,也学了kettle的一些组件的用法.正好趁着机会记录 ...
- HDU 5534:Partial Tree(完全背包)***
题目链接 题意 给出一个n个结点的树,给出n-1个度的权值f[],代表如果一个点的度数为i,那么它对于答案的贡献有f[i].问在这棵树最大的贡献能达到多少. 思路 对于这个图,有n*2-2个度可以分配 ...
- Linux系统下word转pdf,xls转pdf,ppt转pdf
word转换pdf的技术方案,供参考.[doc/docx/ppt/pptx/xls/xlsx均支持转换] 本方案是Java结合shell命令完成,不同于以往的仅依赖java组件转换 ...
- zimg服务器图片数据迁移后,图片404异常的问题解决
由于zimg特殊的图片存储结构及图片命名规则,其迁移数据应该当相当简单的,仅把对应的存储图片数据的文件夹复制即可.往往简单的东西总会有一些成本在里面,下面是我简单的迁移测试过程中遇到的一些问题,仅供参 ...
- Linux 文件系统的基本结构
Linux文件系统为一个倒置的树状结构,所有文件或文件夹均包含在一个根目录/中. Linux系统严格区分大小写所以在Linux中:一个名为“A”的文件夹和一个名为“a”的文件夹是不同的两个文件夹,这点 ...
- 《Graph Neural Networks: A Review of Methods and Applications》阅读笔记
本文是对文献 <Graph Neural Networks: A Review of Methods and Applications> 的内容总结,详细内容请参照原文. 引言 大量的学习 ...
- spring的jar包的下载、说明
spring的jar包官方下载地址:完整链接:https://repo.spring.io/webapp/#/artifacts/browse/tree/General/libs-release-lo ...
- Spring MVC源码(三) ----- @RequestBody和@ResponseBody原理解析
概述 在SpringMVC的使用时,往往会用到@RequestBody和@ResponseBody两个注解,尤其是处理ajax请求必然要使用@ResponseBody注解.这两个注解对应着Contro ...