使用一般处理程序,模拟ASP.NET MVC,开发一个轻量级的学习版MVC框架。
2016-04-16 14:42
971 查看
使用一般处理程序,模拟ASP.NET MVC,开发一个轻量级的学习版MVC框架。
本篇博文是笔者学习MVC的总结有人说MVC是一种设计模式,有人说MVC是一种框架,还有人说MVC是一种思想.
这里是整个项目的文件结构,模型层可以根据需求选用EntityFramework或者直接使用原生的ADO.NET,封装一个SQLHelper,再写一个实例化任意Model的方法.
这里是index.ashx,网站的单一入口点,网站所有的请求都要通过index.ashx处理
using System; using System.Collections.Generic; using System.IO; using System.Reflection; using System.Web; using MVCFrameWork.Controllers; namespace MVCFrameWork { /// <summary> /// index 的摘要说明 /// </summary> public class index : IHttpHandler { //关于HttpContext:在处理请求执行链的各个阶段中, // 会有一个对象在各个对象之间进行传递, // 也即会保存请求的上下文信息, // 这个对象就是HttpContext对象 public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; C(context); //实例化任意控制器,并执行该控制器中的任意动作 } private static void C(HttpContext context) { string controllerName = (context.Request["C"] as string ?? "Home").ToLower();//获取HTTP请求中的控制器 controllerName = controllerName.Substring(0, 1).ToUpper() + controllerName.Substring(1) + "Controller";//容错处理 string actionName = (context.Request["A"] as string ?? "Index").ToLower();//获取HTTP请求中的动作 Assembly assembly = Assembly.GetExecutingAssembly();//获取当前应用程序域中,正在运行的程序集 string assemblyName = assembly.GetName().Name;//反射获取当前解决方案的名称 string controllerTypeName = assemblyName + ".Controllers." + controllerName;//反射获取控制器的类型名,约定大于配置,约定好所有Controller文件,必须存放在Controllers文件夹下 if (File.Exists(context.Server.MapPath("Controllers") + "\\" + controllerName + ".cs"))//判断当前解决方案中,指定的相对目录中,是否存在指定控制器类文件 { Type controllerType = Type.GetType(controllerTypeName);//反射出控制器类型对象 if (!controllerType.IsClass)//如果反射出来的对象不是类,结束方法 return; var controller = Activator.CreateInstance(controllerType);//动态创建控制器的实例 List<string> actions = new List<string>();//创建一个集合存放当前控制器中的所有行为 foreach (var method in controllerType.GetMethods())//反射出控制器对象中的所有方法 { actions.Add(method.Name); } if (actions.Contains(actionName))//检测当前action是否是可调用结构 { try { var action = controllerType.GetMethod(actionName);//反射出指定动作 var actionParameters = action.GetParameters();//反射出参数 var actionAttributes = action.GetCustomAttributes();//反射出自定义特性 foreach (var attr in actionAttributes)//过滤自定义特性 { if((attr is ResPOST) && !context.Request.RequestType.Equals("POST")) { context.Response.Write("执行" + actionName + "失败,该action只响应POST请求"); return; } if (attr is NotAction) { context.Response.Write(actionName+"未定义"); return; } } if (actionParameters.Length >= 1)//反射出参数 { List<object> list = new List<object>(); foreach(var param in actionParameters) { list.Add(context.Request[param.Name]); //根据参数名,获取表单中的参数值并填充到集合中 } action.Invoke(controller,list.ToArray()); //执行带表单参数的action } else { action.Invoke(controller, null); //执行动作,此处只执行无参数的action } } catch { context.Response.Write("执行" + actionName + "失败"); } } else { context.Response.Write("未定义" + actionName + "动作"); } } else { context.Response.Write("未定义" + controllerName + "控制器"); } } public bool IsReusable { get { return false; } } } //林志霄 2016年4月16日 }
自定义的Controller基类
using System; using System.Diagnostics; using System.Runtime.CompilerServices; using System.Web; namespace MVCFrameWork.Controllers { public abstract class MyController { /// <summary> /// 默认加载任意action的对应视图,也可以指定加载哪个视图 /// </summary> /// <param name="context"></param> /// <param name="viewName">视图的名字,使用了编译器特性,默认就是调用者的名称</param> /// <param name="viewData"></param> protected static void View([CallerMemberName]string viewName = "", params object[] viewData) { Debug.WriteLine(viewName); //此处根据视图名字加载对应的视图文件 //约定大于配置,视图文件必须存放在Views文件夹下 } } //自定义特性,标志该方法只响应POST请求 public class NotAction : Attribute { } //自定义特性,标志该方法不是Action方法 public class ResPOST : Attribute { } }
这里是控制器的使用
namespace MVCFrameWork.Controllers { public class IndexController:MyController { public void index() { View(); } [ResPOST] public void login() { View(); } [NotAction] public void getModel() { } } }
相关文章推荐
- 网站后台登录aspcms 提示错误号:-2147467259,错误描述:操作必须使用一个可更新的查询。sql=update AspCms_Content set TimeStatus=0 where TimeStatus=1 and Timeing <= 解决方法。
- ASP.NET MVC 基础(01)
- RaspberryPi2 安装系统到硬盘
- asp 用 PagedDataSource 为 datalist 添加分页需注意
- ASP+JS三级联动下拉菜单
- ASP.NET 页面缓存
- ASP.NET Core 1.0
- 中文VS2008 安装ASP.NET MVC框架问题?
- 中文VS2008 安装ASP.NET MVC框架问题?
- ASP.NET MVC之如何看待内置配置来提高性能优化(四)
- Asp.net 服务器控件
- ASP.NET中使用DataGrid控件按照条件显示GridView单元格的颜色
- 浅谈ASP.NET报表控件
- jasperreport position type 详解
- [转]ExtJs入门之filefield:文件上传的配置+结合Ajax完美实现文件上传的asp.net示例
- OCR图像识别技术-Asprise OCR
- Asp.Net:Repeater 详情 备用
- asp.net页面DataTable转Excel
- Java开源报表JasperReport、iReport4.5.1使用详解(一)
- EDUP无线网卡在 Raspberry配置方法 RTL8188CUS芯片