编程开发 > ASP > 文章内容

ASP.NETWeb应用真实模拟MVC的路由机制

2012-2-11编辑:Sad

ASP.NET Web应用真实模拟MVC的路由机制

 ASP.NET MVC的路由系统通过对HTTP请求的解析得到表示Controller、Action和其他相关的数据,并以此为依据激活Controller对象,调用相应的Action方法,并将方法返回的ActionResult写入HTTP回复中。为了更好的演示其实现原理,我创建一个简单的ASP.NET Web应用来模拟ASP.NET MVC的路由机制。这个例子中的相关组件基本上就是根据ASP.NET MVC的同名组件设计的,只是我将它们进行了最大限度的简化,因为我们只需要用它来演示大致的实现原理而已。

  一、一个通过查询字符串表示Controller和Action的“MVC”程序

  我们的Web应用非常简单。HomeController.cs为定义Controller类型的文件,而Index.html表示HomeController中名称为Index的Action对应的View。我们按照ASP.NET MVC的原理,通过解析请求URL得到Controller和Action的名称。如果Controller为Home,则激活HomeController,如果当前的Action为Index,则将Index.html这个静态文件的内容作为HTTP回复返回。

  我不想定义复杂的解析Controller和Action的逻辑,再这里我直接通过请求URL相应的查询字符串controler和action表示Controller和Action的名称。也就是说如果通过浏览器访问地址http://localhost/mvcapp/?controller=Home&action=Index 可以访问到Index.html中的内容(注:我们并没有将Index.html作为站点的默认页面)。

  接下来我简单的介绍一下是哪些组建促使这个简单的ASP.NET Web应用能够按照MVC的模式来执行。为了使你能够在真正的ASP.NET MVC找到匹配的组件,我们采用了相同的接口和类型名称。

  二、通过Route解析HTTP请求获得路由信息

  我定义了如下一个RouteData类型表示解析HTTP请求得到的Controller和Action等信息。Assemblies和Namespaces表示需要引入的命名空间和程序集,这是因为URL中只能解析出Controller的类型名称,需要相应的命名空间采用得到它的类型全名。如果对应的程序集不曾加载,还需要加载相应的程序集。

   1: public class RouteData
   2: {
   3:     public string Controller { get; set; }
   4:     public string Action { get; set; }
   5:     public IList<string> Assemblies { get; private set; }
   6:     public IList<string> Namespaces { get; private set; }
   7:     public IRouteHandler RouteHandler { get; set; }
   8:  
   9:     public RouteData(string controller, string action, IRouteHandler routeHandler)
  10:     {
  11:         this.Controller = controller;
  12:         this.Action = action;
  13:         this.RouteHandler = routeHandler;
  14:         this.Namespaces = RouteTable.Namespaces;
  15:         this.Assemblies = RouteTable.Assemblies;
  16:     }
  17: }

  真正实现对HTTP请求进行解析并得到RouteData的Route继承自基类RouteBase。我们还定义个了一个表示Route集合的RouteCollection类型,它的GetRouteData方法对集合的所有Route对象进行遍历,并调用其GetRouteData方法。如果得到的RouteData不为空,则返回之。

   1: public abstract class RouteBase
   2: {
   3:     public abstract RouteData GetRouteData(HttpContextBase httpContext);
   4: }
   5:  
   6: public class RouteCollection: Collection<RouteBase>
   7: {
   8:     public RouteData GetRouteData(HttpContextBase httpContext)
   9:     {
  10:         foreach (RouteBase route in this)
  11:         {
  12:             var routeData = route.GetRouteData(httpContext);
  13:             if (null != routeData)
  14:             {
  15:                 return routeData;
  16:             }
  17:         }
  18:         return null;
  19:     }
  20: }

  和ASP.NET MVC一样,我们定义了如下一个RouteTable对象,其静态属性正是一个RouteCollection对象。两个静态属性Namespaces和Assemblies为命名空间和程序集名称的全局维护。

ASP.NET使网页弹出窗口不再困难

热点推荐

登录注册
触屏版电脑版网站地图