使用一般处理程序,模拟ASP.NET MVC,开发一个轻量级的学习版MVC框架。

本文作者通过使用一般处理程序,构建了一个轻量级的MVC学习版框架,探讨了MVC作为设计模式、框架或思想的不同观点。文中展示了项目的文件结构,包括模型层可选的EntityFramework或原生ADO.NET实现,以及网站的单一入口点index.ashx和自定义Controller基类的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用一般处理程序,模拟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() { }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值