3.路由

  1)分析路由/controller/action

 

这段代码忽略了以.axd为文件后缀的URL

routes.IgnoreRoute("{resource}.axd/{*pathInfo}") 

而每一个routes.MapRoute对象中name的值是要唯一的

routes.MapRoute(

                name: "Default",

                url: "{controller}/{action}/{id}",

                defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }

            )

多创建一条路由规则,如果名称相同,会出现错误

 

路由规则定义了{controller}/{action}/,如果只有一个HomeControllerIndex的action的话。交换来输入/Index/Home在url上,会提示无法找到资源。

URL中的controller和action是关键字,无法删除或修改。

 

修改成controller1和action1,出现错误。

但是顺序是可以交换的。我们把actioncontroller换过来。在地址栏写入/index/home成功访问页面。但是一般开发着都遵循/controller/action这种规则。

 

url中controller,action,id的值会以key,value的方式存储到字典中,可用RouteData.value[“id”]取出。

 

2)id传值

最后这个id参数是可选参数,与我们常看到在url后面加上?id=1是一样的意思。把id的值提交给了对应的action

 1.Request.QueryString只能获取以?分隔的参数值。   

 2.RouteData.Values[“id”]就是当前字典上的路由数据,通过访问键名的方式得到键值。

3.Action方法的参数和路由字典的参数是对应的,MVC框架在执行action之前会首先为这些参数赋值。

 

先试验Request.QueryString方法,Index代码修改成如下。

ViewData看起来就是视图数据的意思,[“”]内写上键名,后面给出得到的view值。转到视图,添加

ViewData["idValue"]数据。运行,地址栏输入/Home/Index/?id=99。

 

试验RouteData.Values[“id”]方法,Index代码修改成如下。

运行,地址栏输入/Home/Index/8859

试验Action方法参数取值方法,Index代码修改成如下。

运行,地址栏输入/Home/Index/8521

ViewData[“id”]来对页面传值是比较方便简单的方法。

 

3)URL匹配

 

上面已经分析过actioncontroller是可以换过来的,只要输入的url能够找到对应的控制器和方法是能对应上的。

 

当然还可以打造一些有个性的url,显得高端大气上档次。不过不能定义成{controller}和{action},只能各有一个。其余可以自己命名占位。{}里的词语就是一个占位符。

 

字面值即一个常数字符串,这个字符串可以在大括弧与大括弧之间,也可以在最前面和最后面。

 

1.使用字面量作精确匹配。

现在我们在url前方加入”ftah/”。url: "ftah/{controller}/{action}/{id}",url 看起来就像必然要写这个ftah/的样子。运行程序。

在地址栏输入/Home/Index,出现了无法访问的错误,因为我们url规则必须以ftah/开头。

 

输入/ftah/Home/Index,成功匹配到/Home/Index。

但是两个url参数之间必须用字面量分隔。

 

加上-url输入ch-home/index。完美解决。

2.使用*匹配url剩余部分。

我们把url改成这样,url: "{controller}/{action}/{*plus}"。使用*来匹配URL剩余的部分,最后尾部的URL部分会保存为plus为键名的字典值。

如图修改index方法,获取路由字典信息,同时修改视图中 <p>@ViewData["message"]</p>

运行时没有plus默认参数,视图会显示这样。

地址栏修改成/home/index/pq/da/ca。无论{controller}/{action}/之后有什么东西,一律分配到键名为“plus”对应的值。

2.贪婪匹配

url改成 url:"{controller}/{action}/{plus}ftah{plus1}"。运行。

在地址栏输入/home/index/ftahftahftahmvc。可以看到plus的值是“ftahftah”,证明匹配是从右往左匹配,只要得到了固定的字符”ftah”,之后的全部交给plus来存值。

 

 

4)url默认参数

1.去掉默认值

默认defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }是否重要?先把这段代码去掉。

 

运行。发现没有默认值后无法访问页面。

输入能正确匹配的地址/home/index/1页面才能访问

如果没有使用默认值只能使用完整形式的URL

2.提供部分默认值

现在我们只给controller的默认值,添加代码 defaults: new { controller = "Home" }。

直接运行程序,无法访问页面。

尝试在地址栏输入/index/1。还是显示错误。这是因为mvc不知道你提供的index到底是一个controller还是action。

试试提供后两个参数?修改一下代码。

在地址栏输入/home 成功访问。(这里才显得有意义)

3.url包含字面量

action后面把”/”去掉。跟一个”-”。

直接运行也是无法访问页面

在地址栏输入 /home/index-1。访问成功。

把”-”换成”+”。出现双重转义序列错误。

 

除”-”之外的任意字符的组合,那么字面量相邻的URL参数的默认值是不起作用的。

 

5)url约束

我们可以用正则表达式来对输入的地址进行约束。

url参数加入/{year}/{month}/{day}。

新增一个参数 constraints: new { year = @"\d{4}", month = @"\d{2}", day = @"\d{2}" }

里面的year ,month ,day 对应url的参数名称。@””里面就是写正则表达式。

这里\d{4}是只能输入4个数字,\d{2}只能输入两个数字。

运行,地址栏输入/home/index/1/2222/55/88。成功访问页面。

输入其中一个 不符合正则表达式的数值,页面就无法访问。

6)由路由生成URL

MVC中的路路由是双向的。可用路由生成URL

定义一条普通的url

修改HomeControllerIndex方法。

RouteTable.Routes.GetVirtualPath根据提供的参数生成url。

return Redirect(vp.VirtualPath);返回/执行一个控制器的action方法。这里vp.VirtualPath=/Home/About。

运行程序,通过默认路由转到/Home/Index在转到由我们写的代码生成的url/Home/About。

在定义一条路由,名称Default1,默认值不提供action

Index方法修改如下,指定修改nameDefault1的路由,为期添加action的默认值。

注释默认路由,运行。地址栏输入/Home/Index。

同样跳转到About

规则:默认路由不提供默认值,RouteValueDictionary(new { controller = "Home", action = "About" })必须提供所有url参数值。默认路由提供部分默认值,new RouteValueDictionary(new { action = "Index1" })可以提供所有url参数值,但必须提供缺少默认值的那个参数值。但是由RouteTable.Routes.GetVirtualPath提供的默认值后方的默认路由值将失去作用,这里about是提供的,所以后面默认路由的参数值id无效。

如下图。id改成888001

运行调试,最后只能生成/Home/About

 

特殊情况:

路由url:"ftah/{action}/{id}",

默认参数defaults: new { controller = "Home", action = "Index", id = 100 }

在默认值中定义了 controller,但是在 URL 表达式中却没有这个参数。     在这个时候如果使用RouteTable.Routes.GetVirtualPath 获取 URL,如果设置的外界值提供了这个参数的值, 那么这个参数的值必须和默认值一样,否则就得不到 URLnew RouteValueDictionary(new { controller = "Home"})。

 

默认路由没有参数,也没有默认值,但在GetVirtualPath中添加上了

路由url:"{controller }/{action}/{id}",

默认参数defaults: new { controller = "Home", action = "Index", id = 100 }

RouteTable.Routes.GetVirtualPath(null, "Default1", new RouteValueDictionary(new { a = “a”,b=”b”}));

这样生成的url:/Home/Index/100?a=a&b=b 字符串传参的方式。

 

posted @ 2017-06-26 23:01  飞天阿豪  阅读(226)  评论(0编辑  收藏  举报