深入理解ASP.NET MVC(3)

系列目录

URL是如何通过路由表生成的(outbound)

通常我们被推荐在view设计时使用Html.ActionLink(…)产生链接,这样做的优势就是,url可以根据路由表生成。路由机制的另一个职责便是根据路由表生成url,而不是由我们手动编写。接下来深入分析一下其原理。

类似Html.ActionLink的方法,最终都将通过查询路由表来生成url,跟inbound一样,路由表总是按顺序被依次遍历,直到匹配。每个RouteGetVirtualPath方法负责审查,该方法接受一个RouteValueDictionary参数,该参数实际上就是由相应的Helper提供的。当以下三个条件成立时,认为匹配成功:

一、每个由大括号定义的参数必须能够找到对应的值。按照优先顺序这些值将有下面三种来源:

1.RouteValueDictionary参数明确提供的。也就是我们在调用某些有生成url功能的Helper时提供的,比如ActionLink方法;

2.*从当前请求的上下文的RouteData中;关于这点有更特殊的情况,下面将详细讨论;

3.Route的Defaults中。

二、如果每个Defaults集合中的参数与RouteValueDictionary参数中的值都符合,而且这些值没有在url pattern中用大括号定义,那么认为匹配。听起来有点拗口,下面举个例子.

假如有如下规则:


1

2

3

4

routes.MapRoute( null,

    "manage/orders/{page}",

    new { controller = "Admin",

    action = "OrderManage", page = UrlParameter.Optional });

页面有如下链接:


1

<a href="<%:Url.Action("OrderManage", "Admin") %>">Order</a>

最后生成的链接将是这样的(这里省略了前面的domain):


1

<a href="…/manage/orders">Order</a>

Defaults中有两个参数controller和action,在url的pattern中没有类似{controller}和{action},而且Url.Action的参数同时提供了与Defaults设置一致的参数值(这已经够了),于是这个url是匹配的。

三、每个参数都符合Constraints的匹配规则。

满足上面三个条件后,GetVirtualPath就会将相应的参数填入url中,并最终返回url的字符串。需要强调的一点是:MVC框架的这种行为工作在懒惰模式下,一旦“该要的要到了”,那么就停止继续遍历。这也从另一个角度说明了,把特殊的往前放的黄金原则。

举个例子:

下面是两个有顺序的Route:


1

2

3

4

5

6

7

8

9

10

routes.MapRoute(

                null,

                "manage/car",

                new { controller = "Admin", action = "Car" }

                );

routes.MapRoute(

                null,

                "manage/car/{operation}",

                new { controller = "Admin", action = "Car" }

                );

有一个链接表示:


1

<%: Html.ActionLink("Add Car", "Car","Admin", new { operation = "add" }, null )%>

最后的结果是什么呢?是manage/car/add吗?

其实最后的结果是manage/car,为什么呢?对于第一个Route,它期望的是controller和action这两个参数,而上面的 ActionLink的确完整的提供了这两个参数,而且与Defaults设置一致(这满足规则的第二条),于是匹配了!即使还提供了operation 参数,框架也不管了。显然这不是希望的。只要把两个Route的位置换一下即可。这个例子只是一个演示。

*关于上面条件一的第二小点,其实是个很棒的特性,这里补充一个例子:

假设当前页面的url是:/Catalog/List/Purple/123


1

routes.MapRoute(null, "{controller}/{action}/{color}/{page}");


1

<%: Html.ActionLink("Click me", "List", "Catalog", new {page=789}, null) %>

这个link能匹配这个route吗?也许你认为我没有提供color参数啊,怎么能匹配呢?事实上,结果确出人意料的是:


1

<a href="/Catalog/List/Purple/789">Click me</a>

因为当前页面是/Catalog/List/Purple/123,此时的RouteData保存了color参数值,尽管在ActionLink中没有显示设置color,但是仍然从当前的RouteData中找到了color参数。

再看一个例子:

当前页面的url还是:/Catalog/List/Purple/123


1

routes.MapRoute(null, "{controller}/{action}/{color}/{page}");


1

<%: Html.ActionLink("Click me", "List", "Catalog", new {color="Aqua"}, null) %>

这个link还能匹配这个route吗?也许你认为根据上面的规则应该能,但结果却是无法匹配,为什么呢?因为有个原则,RouteData中的数据只能用于填充url pattern中“靠前的参数”,最后一个参数是不能的!

最后关于outbound还有一个原则,Defaults提供的值,会尽可能的不出现在最终的url结果中。

URL设计原则

在MVC框架下,我们可以对URL做完全的控制,自然就想到要设计出优良的url,URL究竟该如何设计。由于本人web开发经验很少,以下是书中的内容,我做了些概括:

1.url要尽量通俗易懂,不要把技术的东西包含在里面,比如下面这样的:

/Website_v2/CachedContentServer/FromCache/AnnualReport

/my%20great%20article(使用/my-great-article为好)

2.有意义的文本总比ID数字让人感觉舒服

3.不要在url中带有后缀名

4.要有比较强的层次感,又要简短易记,比如:/Products/Menswear/Shirts/Red

5.url要大小写不敏感,并且尽量使用小写字母,mvc框架是大小写不分的

6.不要因为url的变更而弃用老的url,要使用跳转的方式

7.对于只读的操作使用get方式,对于要修改服务器数据的请求使用post方式;url要方便人们保存书签或分享网页,因此,对于分页显示的情况,分页要体现在url中

8.QueryString要尽量少用。当参数是为了参与某种算法,而不是为了直接的资源指向时,可以使用QueryString,因为用户此时不愿意手动输入url。比如page参数

301和302

同样是使客户端浏览器跳转,301是暗示永久跳转,可以暗示搜索引擎这个url将永久不用,当确实需要更形url时考虑;

302表示临时跳转,MVC的RedirectToRouteResult和RedirectResult使用302。

可以像下面这样进行301跳转:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

public static class PermanentRedirectionExtensions

{

    public static PermanentRedirectToRouteResult AsMovedPermanently

        (this RedirectToRouteResult redirection)

    {

        return new PermanentRedirectToRouteResult(redirection);

    }

    public class PermanentRedirectToRouteResult : ActionResult

    {

        public RedirectToRouteResult Redirection { get; private set; }

        public PermanentRedirectToRouteResult(RedirectToRouteResult redirection)

        {

            this.Redirection = redirection;

        }

        public override void ExecuteResult(ControllerContext context)

        {

            // After setting up a normal redirection, switch it to a 301

            Redirection.ExecuteResult(context);

            context.HttpContext.Response.StatusCode = 301;

        }

    }

}


1

2

3

4

public ActionResult MyActionMethod()

{

    return RedirectToAction("AnotherAction").AsMovedPermanently();

}

关于SEO(search engine optimization)

提高排名的技巧:

1.url使用关键字而不是数字

2.url使用较少的QueryString,不要使用下划线

3.单一内容单一url,不要多个url指向相同的内容

4.如果要多个url指向相同的内容,使用301跳转

5.网页的内容要可被“寻址”,要使用get方式,内容不要过于依赖post方式,或者js,flash,silverlight等客户端技术。

劳动果实,转载请注明出处:http://www.cnblogs.com/P_Chou/archive/2010/11/08/details-asp-net-mvc-03.html

时间: 2024-10-13 00:24:07

深入理解ASP.NET MVC(3)的相关文章

深入理解ASP.NET MVC Day1

深入理解ASP.NET MVC ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.NET完全没有关系,是一个全新的Web开发,事实上ASP.NET是创建WEB应用的框架而MVC是能够用更好的方法来组织并管理代码的一种更高级架构体系,所以可以称之为ASP.NET MVC. 我们可将原来的ASP.NET称为 ASP.NET Webforms,新的MVC 称为ASP.NET MVC. ASP.NET Web Form ASP.NET 在过

七天学会ASP.NET MVC (一)——深入理解ASP.NET MVC

ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.NET完全没有关系,是一个全新的Web开发,事实上ASP.NET是创建WEB应用的框架而MVC是能够用更好的方法来组织并管理代码的一种更高级架构体系,所以可以称之为ASP.NET MVC. 我们可将原来的ASP.NET称为 ASP.NET Webforms,新的MVC 称为ASP.NET MVC. ASP.NET Web Form ASP.NET 在过去的十二年里,已经服务并成功实现

深入理解ASP.NET MVC(6)

系列目录 Action全局观 在上一篇最后,我们进行到了Action调用的“门口”: 1 if (!ActionInvoker.InvokeAction(ControllerContext, actionName)) 在深入研究调用过程的细节前,先有一个总体的认识是很有帮助的.InvokeAction方法大致是按照这样的顺序进行的: 查找action:MVC内部查找action的方法似乎有点复杂,涉及到一个ActionDescriptor的东西,但是原理上是通过反射,在以后的文章中会有所涉及.

深入理解ASP.NET MVC(5)

系列目录 回顾 系列的前4节深入剖析了ASP.NET URL路由机制,以及MVC在此基础上是如何实现Areas机制的,同时涉及到inbound和outbound很多细节部分.第2节中提到MvcRouteHandler是MVC框架的入口,这节开始,从MvcRouteHandler往下说开去. Controller的创建过程:Builder和Factory MvcRouteHandler的实现仅仅是通过GetHttpHandler方法返回一个MvcHandler实例,MvcHandler从Route

[转载] ASP.NET MVC (一)——深入理解ASP.NET MVC

个人认为写得比较透彻得Asp.net mvc 文章,所以转载过来,原文链接在最后: ASP.NET vs MVC vs WebForms 许多ASP.NET开发人员开始接触MVC认为MVC与ASP.NET完全没有关系,是一个全新的Web开发,事实上ASP.NET是创建WEB应用的框架而MVC是能够用更好的方法来组织并管理代码的一种更高级架构体系,所以可以称之为ASP.NET MVC. 我们可将原来的ASP.NET称为 ASP.NET Webforms,新的MVC 称为ASP.NET MVC. A

理解ASP.NET MVC中的ActionResult

通常我们在一个ASP.NET MVC项目中创建一个Controller的时候,Index()方法默认的返回类型都是ActionResult,通过查看UML图,ActionResult实际上是一个抽象类,因此实际返回的类型是该抽象类的子类. Ø ActionResult及其子类的UML图   有关ActionResult及其子类的UML图如下所示: 由于图片比较大,所以在浏览器中看起来可能比较小,也不太方便,大家可以点击这里下载大图,使用专业的图片浏览器打开来看. 下载大图 Ø ActionRes

理解ASP.NET MVC中的ModelBinder

模型绑定的本质 任何控制器方法的执行都受action invoker组件(下文用invoker代替)控制.对于每个Action方法的参数,这个invoker组件都会获取一个Model Binder Object(模型绑定器对象).Model Binder的职责包括为Action方法参数寻找一个可能的值(从HTTP请求上下文).每个参数都可以绑定到不同的Model Binder:但是大部分情况我们都使用的是默认模型绑定器-DefaultModelBinder(如果我们没有显式设置使用自定义的Mod

深入理解ASP.NET MVC(7)

系列目录 Action的定位 再次回到Controller的ExecuteCore方法,回到action调用的入口: 1 if (!ActionInvoker.InvokeAction(ControllerContext, actionName)) 这里的ActionInvoker是个IActionInvoke,它无疑是负责了所有action的调用逻辑,MVC中默认实现这个接口的是ControllerActionInvoke.可以想象ControllerActionInvoke面临的第一个问题是

深入理解ASP.NET MVC(1)

系列目录 ASP.NET MVC请求的服务过程 下图是书中的截图,表述了一次通常的ASP.NET MVC请求的服务过程: 从图中可以初步看出一个HttpRequest是如何被ASP.NET和ASP.NET MVC框架执行的:经过IIS和ASP.NET处理后,Core Routing会首先根据URL匹配物理路径上的文件,如果不能匹配则由核心路由模块执行路由,路由被匹配后,MvcRouteHandler会将这个请求“带入”MVC框架,执行Controller和Action,Action可以直接注入r

[学习笔记] 理解ASP.NET MVC的路由系统

引言 路由,正如其名,是决定消息经由何处被传递到何处的过程.也正如网络设备路由器Router一样,ASP.NET MVC框架处理请求URL的方式,同样依赖于一张预定义的路由表.以该路由表为转发依据,请求URL最终被传递给特定Controller的特定Action进行处理.而在相反的方向上,MVC框架的渲染器同样要利用这张路由表,生成最终的HTML页面并返回URL.所以,理解整个ASP.NET MVC的路由系统,有两个必须出现的关键元素:Controller与Action,有两个方向的操作:传入的