mvc基础系列说谈(1)——route

准备工作

(1)NewsController

用于处理新闻相关业务。

先给它添加NewsList,与Detail两个动作。

其中一个用于显示新闻列表,另一个用于显示新闻详细

 

(一)route的作用

routeUrl中得到参数并传递给相应的Controller

 

(二)路由的匹配

现在asax文件中定义了两个路由:

routes.MapRoute(
    
" NewsList " ,
    
" {controller}/{action}.aspx/{id} " ,
    
new  { controller  =   " News " , action  =   " NewsList " , id  =   ""  }
); 

routes.MapRoute(
    
" Detail " ,
    
" {controller}/{action}/{id} " ,
    
new  { controller  =   " News " , action  =   " Detail " , id  =   1  },
    
new  { id = @" \d+ " }
);

 

 

当在地址栏中请求时,地址News/NewsList与路由表尝试匹配。路由表第一个路由:NewsList,它的匹配规则是

{controller}/{action}.aspx/{id}(其中.aspx部分是作为常量来进行)

现在的地址由路由得到的参数是:{News}/{NewsList}/ 这时,就出现了动作不匹配,所以从路由表下一个路由来匹配。

第二个路由规则是:{controller}/{action}/{id},这时由路由解析出来的参数与其相符,所以使用这个路由规则来进行下一步工作。

下一步的工作是定位到相应的控制器来执行相应的运用,返回相应的视图。

查找NewsController 控制器,并路由到public ActionResult NewsList()动作,返回动作中的视图,这个视图由Views文件夹中的以控制器命名的子文件夹中的NewsList视图文件来呈现用户请求界面。

 

所以,访问这个Url得到的页为:

mvc基础系列说谈(1)——route

 

(三)路由的定义

在一个route中,通过在大括号中放一个占位符来定义( { and } )。当解析URL的时候,符号"/""."被作为一个定义符来解析,而定义符之间的值则匹配到占位符中。route定义中不在大括号中的信息则作为常量值。例如:

{controller}/{action}.aspx/{id}

导航到routes.MapRoute方法,查看它的定义。

它作为RouteCollection的一个扩展方法来使用。

        // 摘要:

        //Maps the route.

        // 参数:

        //routes:

        //The routes.

        //name:

        //The name.

        //url:

        //he URL.

        //defaults:

        //he defaults.

        //constraints:

        //The constraints.

 

public   static  Route MapRoute( this  RouteCollection routes,  string  name, 
                     
string  url,  object  defaults,  object  constraints);

这里贴出其中的一个。

其中的url部分就是{controller}/{action}.aspx/{id}这部分。第一部分用于路由Controller,第二部分用于路由action,其它的作为传递参数(可以这样理解)。

object defaults就是默认值:new { controller = "News", action = "Detail", id = 1 }

这个部分controlleractionid不能改名,但不区分大小写。

 

asax文件中定义的路由规则,它们的顺序很重要,对于精细控制的路由规则应该靠前,而默认的,笼统的路由规则在最下边。

(四)路由约束

在第一个路由中

new { id = @"\d*" }

这个部分就是约束的部分,用于约束id0到多个数字组成,它由正则来实现。当url的参数部分(id)为非数字时,会跳过这个路由,而尝试由下一个路由来匹配。

(五)自定义路由约束

自定义约束要实现IrouteConstraint接口

        //     Determines whether the URL parameter contains a valid value for this constraint.

        //

        // 参数:

        //   httpContext:

        //     An object that encapsulates information about the HTTP request.

        //

        //   route:

        //     The object that this constraint belongs to.

        //

        //   parameterName:

        //     The name of the parameter that is being checked.

        //

        //   values:

        //     An object that contains the parameters for the URL.

        //

        //   routeDirection:

        //     An object that indicates whether the constraint check is being performed

        //     when an incoming request is being handled or when a URL is being generated.

        //

        // 返回结果:

        //     true if the URL parameter contains a valid value; otherwise, false.

       

bool  Match(HttpContextBase httpContext,Route route,  string  parameterName, 
RouteValueDictionary values, RouteDirection routeDirection); 

 

现在自定义约束,还是实现,对detail请求时,id只能是数字。(官网上提供的示例是只可以让本地127.0.0.1访问) 

public   class  SelfConstraint : IRouteConstraint
{
    
public   bool  Match(HttpContextBase httpContext, Route route,  string  parameterName, 
                          RouteValueDictionary values, RouteDirection routeDirection)
        {
            
if  (values.Count  >   0 )
            { 
                
int  k;
                
if  (Int32.TryParse(values[ " id " ].ToString(),  out  k))
                    
return   true ;
                
return   false ;
            }
            
return  httpContext.Request.IsLocal;
        }
}

 

如果id(这里通过kv对来访问)是数字,则可以路由,否则,由路由表的下一个路由去匹配控制器。

routes.MapRoute(
     
" Detail " ,
     
" {controller}/{action}/{id} " ,
     
new  { Controller  =   " News " , action  =   " Detail " , id  =   2  },
     
// new { id = @"\d*" }
      new  { id = new  SelfConstraint()}
 );

 

在路由表添加的时候,创建实例引用就可以了。如果请求的Url符合路由约束,则由这个路由规则去路由,否则转向下一个路由。

 

你可能感兴趣的:(route)