• mvc模拟实现


    1.定义httpmodule
      <system.webServer>
        <modules>    
          <add name="UrlRoutingModule"  type="WebApp.UrlRoutingModule,WebApp"/>
        </modules>
        <validation validateIntegratedModeConfiguration="false" />
      </system.webServer>
    2.对应的mvc类
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Reflection;
    using System.Web;
    using System.Web.Compilation;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    
    namespace WebApp
    {
        /// <summary>
        /// 二次封装的请求上下文:包括原始的HttpContextBase和经过提取的路由数据对象
        /// </summary>
        public class RequestContext
        {
            public virtual HttpContextBase HttpContext { get; set; }
            public virtual RouteData RouteData { get; set; }
        }
        public interface IRouteHandler
        {
            IHttpHandler GetHttpHandler(RequestContext requestContext);
        }
        public abstract class RouteBase
        {
            public abstract RouteData GetRouteData(HttpContextBase httpContext);
        }
        public class RouteData
        {
            public IDictionary<string, object> Values { get; private set; }
            public IDictionary<string, object> DataTokens { get; private set; }
            public IRouteHandler RouteHandler { get; set; }
            public RouteBase Route { get; set; }
            public RouteData()
            {
                this.Values = new Dictionary<string, object>();
                this.DataTokens = new Dictionary<string, object>();
                this.DataTokens.Add("namespaces", new List<string>());
            }
            public string Controller
            {
                get
                {
                    object controllerName = string.Empty;
                    this.Values.TryGetValue("Controller", out controllerName);
                    return controllerName.ToString();
                }
            }
            public string ActionName
            {
                get
                {
                    object actionName = string.Empty;
                    this.Values.TryGetValue("Action", out actionName);
                    return actionName.ToString();
                }
            }
    
        }
        public class Route : RouteBase
        {
            public IRouteHandler RouteHandler { get; set; }
            public string Url { get; set; }
            public IDictionary<string, object> DataTokens { get; set; }
            public Route()
            {
                this.DataTokens = new Dictionary<string, object>();
                this.RouteHandler = new MvcRouteHandler();
            }
            public override RouteData GetRouteData(HttpContextBase httpContext)
            {
                IDictionary<string, object> variables;
                //如 AppRelativeCurrentExecutionFilePath的值~/home/index,前两个是~/我们从第三位取值,
                //所以substring(2)的结果是home/index match返回返回符合路由规则的路由参数这里 字典里controller:"home",action:"index"
                if (this.Match(httpContext.Request.AppRelativeCurrentExecutionFilePath.Substring(2), out variables))
                {
                    RouteData routeData = new RouteData();
                    foreach (var item in variables)
                    {
                        routeData.Values.Add(item.Key, item.Value);
    
                    }
                    foreach (var item in DataTokens)
                    {
                        routeData.DataTokens.Add(item.Key, item.Value);
    
                    }
                    routeData.RouteHandler = this.RouteHandler;
                    return routeData;
                }
                return null;
            }
    
            protected bool Match(string requestUrl, out IDictionary<string, object> variables)
            {
                variables = new Dictionary<string, object>();
                string[] strArray1 = requestUrl.Split('/');
                string[] strArray2 = this.Url.Split('/');//其中的某条路由规则
                if (strArray1.Length != strArray2.Length)
                {
                    return false;
                }
                for (int i = 0; i < strArray2.Length; i++)
                {
                    if (strArray2[i].StartsWith("{") && strArray2[i].EndsWith("}"))
                    {
                        variables.Add(strArray2[i].Trim("{}".ToCharArray()), strArray1[i]);
                    }
                }
                return true;
            }
        }
    
        public class RouteTable
        {
            public static RouteDictionary Routes { get; private set; }
            static RouteTable()
            {
                Routes = new RouteDictionary();
            }
    
        }
    
        public class RouteDictionary : Dictionary<string, RouteBase>
        {
            public RouteData GetRouteData(HttpContextBase httpContext)
            {
                //便利global.asax添加的路由规则
                foreach (RouteBase route in this.Values)
                {
                    //比如获取得到其中的某一条路由规则 "{Controller}/{Action}" 比如我们请求地址/home/index 对应的数据层次就像routeData.Value=["Controller":"home","Action":"index"]
                    //routeData.RouteHandler=MvcHandler
                    RouteData routeData = route.GetRouteData(httpContext);
                    if (routeData != null)
                    {
                        return routeData;
                    }
                }
                return null;
            }
        }
        public class UrlRoutingModule : IHttpModule
        {
            public void Dispose()
            {
    
            }
    
            public void Init(HttpApplication context)
            {
                context.PostResolveRequestCache += onPostResolveRequestCache;
            }
    
            public virtual void onPostResolveRequestCache(object sender, EventArgs e)
            {
                HttpContextWrapper httpContext = new HttpContextWrapper(HttpContext.Current);
                RouteData routeData = RouteTable.Routes.GetRouteData(httpContext);
                if (routeData == null)
                {
                    return;
                }
                RequestContext requestContext = new RequestContext
                {
    
                    RouteData = routeData,
                    HttpContext = httpContext
                };
                IHttpHandler handler = routeData.RouteHandler.GetHttpHandler(requestContext);//这里返回MvcHandler
                httpContext.RemapHandler(handler);//UrlRoutingModule使用MvcHandler处理器处理,调用响应的processrequest方法
    
            }
        }
        public class MvcRouteHandler : IRouteHandler
        {
            public IHttpHandler GetHttpHandler(RequestContext requestContext)
            {
                return new MvcHandler(requestContext);
            }
        }
        public class MvcHandler : IHttpHandler
        {
            public bool IsReusable
            {
                get
                {
                    return false;
                }
            }
            public RequestContext RequestContext { get; private set; }
            public MvcHandler(RequestContext requestContext)
            {
                this.RequestContext = requestContext;
            }
            public void ProcessRequest(HttpContext context)
            {
                string controllerName = this.RequestContext.RouteData.Controller;
                IControllerFactory controllerFactory = ControllerBuilder.Current.GetControllerFactory();
                IController controller = controllerFactory.CreateController(this.RequestContext, controllerName);
                controller.Execute(this.RequestContext);
            }
        }
        public interface IController
        {
            void Execute(RequestContext requestContext);
        }
        public interface IControllerFactory
        {
            IController CreateController(RequestContext requestContext, string controllerName);
        }
        public class ControllerBuilder
        {
            private Func<IControllerFactory> factoryThunk;
            public static ControllerBuilder Current { get; private set; }
            static ControllerBuilder()
            {
                Current = new ControllerBuilder();
            }
            public IControllerFactory GetControllerFactory()
            {
                return factoryThunk();
            }
            public void SetControllerFactory(IControllerFactory controllerFactory)
            {
                factoryThunk = () => controllerFactory;
            }
        }
        public class DefaultControllerFactry : IControllerFactory
        {
            private static List<Type> controllerTypes = new List<Type>();
            /// <summary>
            /// 构造函数加载所有的控制器类的类型放在controllerTypes
            /// </summary>
            static DefaultControllerFactry()
            {
                foreach (Assembly assembly in BuildManager.GetReferencedAssemblies())
                {
                    foreach (Type type in assembly.GetTypes().Where(type => typeof(IController).IsAssignableFrom(type)))
                    {
                        controllerTypes.Add(type);
                    }
                }
            }
    
    
            /// <summary>
            /// 通过controllerTypes集合和具体的控制器名称controllerName,反射创建对应控制器
            /// </summary>
            /// <param name="requestContext"></param>
            /// <param name="controllerName"></param>
            /// <returns></returns>
            public IController CreateController(RequestContext requestContext, string controllerName)
            {
                string typeName = controllerName + "Controller";
                Type controllerType = controllerTypes.FirstOrDefault(c => string.Compare(typeName, c.Name, true) == 0);
                if (controllerType == null)
                {
                    return null;
                }
                return (IController)Activator.CreateInstance(controllerType);
            }
        }
    
        public class ControllerBase : IController
        {
            protected IActionInvoker ActionInvoker { get; set; }
            public ControllerBase()
            {
                this.ActionInvoker = new ControllerActionInvoker();
            }
            public void Execute(RequestContext requestContext)
            {
                ControllerContext context = new ControllerContext
                {
                    RequestContext = requestContext,
                    Controller = this
                };
                string actionName = requestContext.RouteData.ActionName;
                this.ActionInvoker.InvokeAction(context, actionName);
            }
        }
        public interface IActionInvoker
        {
            void InvokeAction(ControllerContext context, string actionName);
        }
        /// <summary>
        /// 控制器上下文:包含控制器和二次封装过的RequestContext请求上下文
        /// </summary>
        public class ControllerContext
        {
            /// <summary>
            /// 包含使用的控制器
            /// </summary>
            public ControllerBase Controller { get; set; }
            public RequestContext RequestContext { get; set; }
        }
        public class ControllerActionInvoker : IActionInvoker
        {
            public IModelBinder ModelBinder { get; private set; }
            public ControllerActionInvoker()
            {
                this.ModelBinder = new DefaultModelBinder();
            }
            public void InvokeAction(ControllerContext controllerContext, string actionName)
            {
                MethodInfo method = controllerContext.Controller.GetType().GetMethods()
                    .First(m => string.Compare(actionName, m.Name, true) == 0);
                List<object> parameters = new List<object>();
                foreach (ParameterInfo parameter in method.GetParameters())
                {
                    //把请求的参数绑定对应方法参数的模型上
                    parameters.Add(this.ModelBinder.BindModel(controllerContext,
                        parameter.Name, parameter.ParameterType));
                }
                ActionResult actionResult = method.Invoke(controllerContext.Controller, parameters.ToArray()) as ActionResult;
                actionResult.ExecuteResult(controllerContext);
            }
        }
        public interface IModelBinder
        {
            object BindModel(ControllerContext controllerContext, string modelName, Type modelType);
        }
        public class DefaultModelBinder : IModelBinder
        {
            public object BindModel(ControllerContext controllerContext, string modelName, Type modelType)
            {
                if (modelType.IsValueType || typeof(string) == modelType)
                {
                    object instance;
                    if (GetValueTypeInstance(controllerContext, modelName, modelType, out instance))
                    {
                        return instance;
                    }
                    return Activator.CreateInstance(modelType);
                }
                object modelInstance = Activator.CreateInstance(modelType);
                foreach (PropertyInfo property in modelType.GetProperties())
                {
                    if (!property.CanWrite || (!property.PropertyType.IsValueType
                        && property.PropertyType != typeof(string)))
                    {
                        continue;
    
                    }
                    object propertyValue;
                    if (GetValueTypeInstance(controllerContext, property.Name, property.PropertyType, out propertyValue))
                    {
                        property.SetValue(modelInstance, propertyValue, null);
                    }
                }
                return modelInstance;
            }
            private bool GetValueTypeInstance(ControllerContext controllerContext, string modelName, Type modelType, out object value)
            {
                System.Collections.Specialized.NameValueCollection form = HttpContext.Current.Request.Form;
                string key;
                if (null != form)
                {
                    key = form.AllKeys.FirstOrDefault(k => string.Compare(k, modelName, true) == 0);
                    if (key != null)
                    {
                        value = Convert.ChangeType(form[key], modelType);
                        return true;
                    }
    
                }
                key = controllerContext.RequestContext.RouteData.Values
                    .Where(item => string.Compare(item.Key, modelName, true) == 0)
                    .Select(item => item.Key).FirstOrDefault();
                if (null != key)
                {
                    value = Convert.ChangeType(controllerContext.RequestContext.RouteData.Values[key], modelType);
                    return true;
                }
                key = controllerContext.RequestContext.RouteData.DataTokens
                    .Where(item => string.Compare(item.Key, modelName, true) == 0)
                    .Select(item => item.Key).FirstOrDefault();
    
                if (null != key)
                {
                    value = Convert.ChangeType(controllerContext.RequestContext.RouteData.DataTokens[key], modelType);
                    return true;
                }
                value = null;
                return false;
            }
    
        }
        public abstract class ActionResult
        {
            public abstract void ExecuteResult(ControllerContext context);
        }
        public class RawContentResult : ActionResult
        {
            public string RawData { get; private set; }
            public RawContentResult(string rawData)
            {
                RawData = rawData;
            }
            public override void ExecuteResult(ControllerContext context)
            {
                context.RequestContext.HttpContext.Response.Write(this.RawData);
            }
        }
        public class SimpleModel
        {
            public string Controller { get; set; }
            public string Action { get; set; }
        }
        public class HomeController : ControllerBase
        {
            public ActionResult Index(SimpleModel model)
            {
                string content = string.Format("Controller:{0}<br/>Action:{1}", model.Controller, model.Action);
                return new RawContentResult(content);
            }
        }
        public partial class WebForm1 : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
    
            }
        }
    }
    3.global.asax
    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Linq;
    using System.Reflection;
    using System.Web;
    using System.Web.Compilation;
    using System.Web.Optimization;
    using System.Web.Routing;
    using System.Web.Security;
    using System.Web.SessionState;
    
    namespace WebApp
    {
        public class Global : HttpApplication
        {
            void Application_Start(object sender, EventArgs e)
            {
                // 在应用程序启动时运行的代码
                //RouteConfig.RegisterRoutes(RouteTable.Routes);
                //BundleConfig.RegisterBundles(BundleTable.Bundles);
    
                RouteTable.Routes.Add("default",
                    new Route { Url = "{Controller}/{Action}" });
    
                ControllerBuilder.Current.SetControllerFactory(new DefaultControllerFactry());
            }
        }
    
    }
  • 相关阅读:
    1-6.webpack对字体图标和图片的处理
    1-5.Webpack对Html模板处理
    1-4.Webpack对样式的处理
    1-3.Webpack对脚本的处理
    1-2.Webpack初始化
    1-1.mmall电商项目搭建
    Java 随心笔记11
    Java 随心笔记10
    Java 随心笔记9
    Java 随心笔记8
  • 原文地址:https://www.cnblogs.com/kexb/p/8325574.html
Copyright © 2020-2023  润新知