调用流程,不多阐述,请看下图
下面通过代码执行流程演示
1.浏览器请求:http://localhost/SimpleMvc/Home/Index
2.在Global.asax文件的Application_Start方法中注册路由服务
protected void Application_Start(object sender, EventArgs e) { RouteTable.Routes.Add("default", new Route("{controller}/{action}",new SimpleRouteHandler())); }
controlleraction会直接映射为路由表中的keyValue键值,方便下一步路
3. 1的url会通过路由表进入IRouteHandler(自定义SimpleRouteHandler)
public class SimpleRouteHandler:IRouteHandler { public IHttpHandler GetHttpHandler(RequestContext requestContext) { return new SimpleHttpHandler(requestContext.RouteData.Values); } }
这里只是演示mvc的原理,因此只将路由相关的数据传递下去,实际场景中还有很多其他的参数需要映射和传
4.参考上面的实现,我们这里只把路由数据传递给IHttpHandler(自定义SimpleHttpHandler)
public class SimpleHttpHandler:IHttpHandler { public SimpleHttpHandler(RouteValueDictionary routeData) { _routeData = routeData; } private RouteValueDictionary _routeData; public bool IsReusable { get { throw new NotImplementedException(); } } /// <summary> /// 通过controller,action激活Controller,然后执行Action,返回结果 /// </summary> /// <param name="context"></param> public void ProcessRequest(HttpContext context) { var model = new SimpleModle(); model.Controller =_routeData["controller"].ToString(); model.Action =_routeData["action"].ToString(); var control = ControllerFactory.Instance.GetController(model.Controller); if (control!=null) { var view = control.Excute(model.Action, new object[] { model }); if (view!=null) { context.Response.Write(view); return; } } context.Response.Write("<h3>不支持该请求</h3>"); } }
4.1如何激活controller可以参考以下代码
public class ControllerFactory { private ControllerFactory() { } static ControllerFactory() { } private const string END = "Controller"; private static object syn = new object(); private Dictionary<string, Type> _contrDc = new Dictionary<string, Type>(); public static readonly ControllerFactory Instance = new ControllerFactory(); /// <summary> /// 根据controller名称返回实例 /// </summary> /// <param name="controllerName"></param> /// <returns></returns> public IController GetController(string controllerName) { if (!string.IsNullOrEmpty(controllerName)) { if (!controllerName.EndsWith(END)) { controllerName += END; } if (!_contrDc.ContainsKey(controllerName)) { lock (syn) { if (!_contrDc.ContainsKey(controllerName)) { var type = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(s => typeof(IController).IsAssignableFrom(s) && string.Equals(s.Name, controllerName, StringComparison.InvariantCultureIgnoreCase)); _contrDc.Add(controllerName, type); } } } if (_contrDc[controllerName] != null) { return (IController)Activator.CreateInstance(_contrDc[controllerName]); } } return null; } }
4.2,controller如何执行action,可以参考一下代码
public interface IController { object Excute(string action, object[] parameters); } public abstract class ControllerBase : IController { public virtual object Excute(string action,object[] parameters) { var method = this.GetType().GetMethod(action); if (method!=null) { return method.Invoke(this, parameters); } return null; } } public class HomeController : IController { public object Excute(string action, object[] parameters) { var model = parameters[0] as SimpleModle; string content = "参数无效"; if (model != null) { content = string.Format("Controller:{0}<br/>Action:{1}", model.Controller, model.Action); } return new RawContentResult(content); } }
4.3 简单的Modle
public class SimpleModle { public string Controller { get; set; } public string Action { get; set; } }
4.4 简单的view
public abstract class ActionResult { } class RawContentResult : ActionResult { public RawContentResult(string content) { Content = content; } public string Content { get; set; } public override string ToString() { return Content; }
5.返回结果: