技术开发 频道

借助Web模拟程序 了解ASP.NET MVC运行

        通过MvcHandler处理请求

  在UrlRoutingModule映射的实际上是具有如下定义的MvcHandler,它具有一个RequestContext属性通过构造函数进行初始化。在ASP.NET MVC中,真正的请求处理体现在根据路由信息创建Controller,并执行相应的Action方法。这两个步骤体现的ProcessRequest方法中。

1: public class MvcHandler: IHttpHandler  
2: {  
3:     public RequestContext RequestContext{get; private set;}  
4:     public IControllerFactory ControllerFactory  
5:     {  
6:         get { return ControllerBuilder.Current.GetControllerFactory(); }  
7:     }  
8:     public MvcHandler(RequestContext requestContext)  
9:     {  
10:         this.RequestContext = requestContext;  
11:     }  
12:     public bool IsReusable  
13:     {  
14:         get { return false; }  
15:     }  
16:     public void ProcessRequest(HttpContext context)  
17:     {  
18:         RouteData routeData = this.RequestContext.RouteData;  
19:         var controller =  this.ControllerFactory.CreateController(this.RequestContext, routeData.Controller);  
20:         controller.Execute(this.RequestContext);  
21:     }  
22: }

        Controller实现了具有如下定义的接口IController,所有Action方法都通过Execute方法执行,该方法的参数的表示当前请求上下文的RequestContext对象。IController通过相应的Controller工厂创建,下面的代码同时也定义了Controller工厂接口的定义。

1: public interface IController  
2: {  
3:     void Execute(RequestContext requestContext);  
4: }  
5: public interface IControllerFactory  
6: {  
7:     IController CreateController(RequestContext requestContext, string controllerName);  
8: }

  我们定义了如下一个简单名称为DefaultController,它的Execute方法定义很简单:通过包含在RequestContext的RouteData得到当前的Action,并将它作为方法名得到相应的MethodInfo对象,滨个通过反射调用它得到一个ActionResult对象,最后执行ActionResult的ExecuteResult方法。该方法的参数是基于RequestContext创建的另一个上下文ControllerContext。

1: public class DefaultController : IController  
2: {  
3:     public void Execute(RequestContext requestContext)  
4:     {  
5:         string action = requestContext.RouteData.Action;  
6:         MethodInfo method = this.GetType().GetMethod(action);  
7:         ActionResult result = (ActionResult)method.Invoke(this, null);  
8:         ControllerContext controllerContext = new ControllerContext  
9:         {  
10:             RequestContext = requestContext  
11:         };  
12:         result.ExecuteResult(controllerContext);  
13:     }  
14: }

  我们定义了具有如下定义的Controller工厂类DefaultControllerFactory。创建Controller的逻辑也不复杂:通过RouteData表示的Controller名称得到相应的Controller类型,通过反射创建Controller对象。由于RouteData中只包含Controller的名称,所以需要通过命名空间和程序集的辅助才能解析出真正的类型。

1: class DefaultControllerFactory : IControllerFactory  
2: {  
3:     public IController CreateController(RequestContext requestContext, string controllerName)  
4:     {  
5:         RouteData routeData = requestContext.RouteData;  
6:         string controllerType = string.Format("{0}Controller", controllerName);  
7:         IController controller;  
8:         controller = this.CreateControler(controllerType);  
9:         if (null != controller)  
10:         {  
11:             return controller;  
12:         }  
13:         foreach (string assembly in routeData.Assemblies)  
14:         {  
15:             controller = this.CreateControler(controllerType, assembly);  
16:             if (null != controller)  
17:             {  18:                 return controller;  
19:             }  
20:    
21:             foreach (string ns in routeData.Namespaces)  
22:             {  
23:                 controllerType = string.Format("{0}.{1}Controller", ns, controllerName);  
24:                 controller = this.CreateControler(controllerType, assembly);  
25:                 if (null != controller)  
26:                 {  
27:                     return controller;  
28:                 }  
29:             }  
30:         }  
31:    
32:         throw new InvalidOperationException("Cannot locate the controller");  
33:     }  
34:     private IController CreateControler(string controllerType, string assembly = null)  
35:     {  
36:         Type type = null;  
37:         if (null == assembly)  
38:         {  
39:             type = Type.GetType(controllerType);  
40:         }  
41:         else  
42:         {  
43:             type = Assembly.Load(assembly).GetType(controllerType);  
44:         }  
45:         if (null == type)  
46:         {  
47:             return null;  
48:         }  
49:         return Activator.CreateInstance(type) as IController;  
50:     }  
51: }

  将ActionResult写入Http回复

  Controller的Action方法的返回值为具有如下定义的ActionResult类型,通过ExecuteResult方法将相应的执行结果写入HTTP回复中。我定义了如下一个StaticViewResult,它根据RouteData中的Action信息找到匹配的.html静态文件,并将文件的内容写入HttpResponse。

1: public abstract class ActionResult  
2: {  
3:     public abstract void ExecuteResult(ControllerContext context);  
4: }  
5:    
6: public class StaticViewResult: ActionResult  
7: {  
8:     public override void ExecuteResult(ControllerContext context)  
9:     {  
10:         context.RequestContext.HttpContext.Response.WriteFile(context.RequestContext.RouteData.Action + ".html");  
11:     }  
12: }

  实例的配置和定义

  在我们的实例中定义的HomeController定义如下,在表示Action的Index方法中,直接返回一个StaticViewResult对象。

1: public class HomeController : DefaultController  
2: {  
3:     public ActionResult Index()  
4:     {  
5:         return new StaticViewResult();  
6:     }  
7: }

        然后在配置中进行了针对UrlRoutingModule的注册,仅此而已。

1: <configuration>  
2:   <system.webServer>  
3:     <modules>  
4:       <add name="UrlRoutingModule" type="Artech.MvcRouting.UrlRoutingModule, Artech.MvcRouting"/>  
5:     </modules>  
6:   </system.webServer>  
7: </configuration>

  出处:http://artech.cnblogs.com

  原文链接:http://www.cnblogs.com/artech/archive/2011/12/05/asp-mvc-how-to-work.html

0
相关文章