004_URL 路由 - 高级路由特性

在视图中生成输出URL

   使用路由系统来生成输出URL,能够确保URL方案动态地产生URL。

   在视图中生成输出URL的最简单做法是在视图中调用Html.ActionLink辅助器方法,如:

<div>@Html.ActionLink("This is an outgoing URL", "CustomVariable")</div>

注意,ActionLink方法生成的HTML是基于当前路由配置的。如果路由方案是下面这样,

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = UrlParameter.Optional });
        }

   则将得到这样的:HTML:<a href=”/Home/CustomVarible”>This is an outgoing URL</a>

   但是,如果将路由方案改为下面这种方式:

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute("NewRoute", "App/Do{action}",
                new { controller = "Home" });
            routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = UrlParameter.Optional });
        }

   则将会得到:<a href=”/App/DoCustomVarible”>This is an outgoing URL</a>

   因此,可以看出使用路由系统生成输出URL的方式可以方便的实现自动对路由配置的更改进行响应。这也方便了维护——通过修改路由方案,在视图中的输出链接会自动地反映出这种修改。

知识点:

         路由系统是按照路由被添加的顺序来处理路由的,路由会被添加到传递给RegisterRoutes方法的RuteCollection对象中。每一条路由再被检测是否是一个匹配时,都需要满足三个条件:

  • URL模式中定义的每一个片段变量都必须有一个可用的值。为了找到每个片段变量的值,路由系统首先查看已经提供的值(采用匿名类型的属性),然后查看当前请求的变量值,最后查看该路由中定义的默认值。
  • 在给片段变量提供的值中,应当没有违背这条路由所定义的只默认变量的值。只默认变量是为其提供了默认值,但未在URL模式中出现的变量。如在匹配这条路由(routes.MapRoute("MyRoute", "{controller}/{action}",new { myVar = "True" });)时就要小心,不要给myVar(只默认变量:为其提供了默认值“true”,但未在URL模式中出现——如果未在URL模式中为其提供值)提供值,或要确保所提供的值与这个默认值是匹配的。
  • 所有片段变量的值均必须满足路由约束。一定注意,路由系统不会试图查找最佳匹配路由,它只会找出最先匹配者,然后用这条路由来生成URL,任何后续的路由都会被忽略。所以,应该首先定义最具体的路由。

为各个片段参数所选择参数值将在其中被替换,即在Html.ActionLink给片段提供的值,会替换掉生成URL中的相关默认值——这些默认值是在路由配置中设定的。同时,将忽略尾部的默认值序列。如果明确地提供一些参数,但它们与片段参数或默认参数不符,那么方法将把这些参数以“名字/值”对的查询字符串形式进行追加。

以其他控制器为目标

   ActionLink方法默认以当前控制器为目标创建输出URL,如果需要创建一个以不同控制器为目标的输出URL,则可以使用它的一个重载版本,它允许指定控制器名称。需要注意的是,路由系统不会对动作方法和控制器的值进行检验,不要指定不存在的目标。

@{
    Layout = null;
}

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>ActionName</title>
</head>
<body>
    <div>The controller is:@ViewBag.Controller</div>
    <div>The action is:@ViewBag.Action</div>
    <div>@Html.ActionLink("This is an outgoing URL", "CustomVariable")</div>
    <div>
        <!--通过指定控制器来实现一个以不同控制器为目标的输出 URL -->
        @Html.ActionLink("This targets another controller", "Index", "Admin")
    </div>
</body>
</html>

   上述加粗部分使用了ActionLink的一个重载版本,其指定了目标控制器及动作,当视图渲染时,最终会生成以下HTML结果:<a href=”/Admin”>This targets another controller</a>。由于Index为默认动作方法,因此,可以省略默认的动作片段,这也是路由系统所允许的。

传递额外的值

   可以使用一个匿名类型为一些片段变量传值,在这个匿名类型中一其属性表示片段。如下代码所示:

    <div>
        <!--使用匿名类型给片段变量提供值-->
        @Html.ActionLink("This is an outgoing URL", "CustomVariable", new { id = "Hello" })
    </div>

上面这段代码将会产生这样的HTML:

<a href="/App/DoCustomVariable?id=Hello">This is an outgoing URL</a>

   根据前面的路由模式设置,为id提供的值被作为查询字符串添加到了URL,其原因是为了实现与路由设置的URL模式相匹配。前面的路由设置如下:

routes.MapRoute("NewRoute", "App/Do{action}",new { controller ="Home" });

因此,如果路由设置中只有一个与之匹配的路由,那将会得到不同的结果——复制给id属性的值被作为URL片段包括在URL中。即如果只有一条这样的与之匹配的路由:

routes.MapRoute("MyRoute", "{controller}/{action}/{id}",
                new { controller = "Home", action = "Index", id = UrlParameter.Optional });

   HTML结果:<a href="/App/CustomVariable/Hello">This is an outgoing URL</a>

变化之处已用粗体标出。

知识点:

片段变量的重用

   在为一条路由URL模式中的每一个片段变量查找值的过程中,路由系统将考查当前请求的值,就如前面谈到输出URL时所说的,路由系统为了找到每个片段变量的值,会首先查看已经提供的值(采用匿名类型的属性),然后查看当前请求的变量值,最后查看该路由定义的默认值。

   假设只有一条路由,如下:

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

   现在假设一个用户的当前URL为/Catalog/List/Purple/123,并渲染一个这样的链接:

@Html.Action(“Click me”,”List”,”Catalog”,new {page=789},null)

   虽然,未提供color片段变量的值,同时也未定义默认值,但路由系统将会根据已经的定义的路由进行匹配,并生成这样的HTML:

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

   原因是,路由系统查找了当前请求的变量值——它重用了输入URL的片段变量值,color的值最终被赋成了Purple。

   需要注意的是,在开发的过程中不要依赖路由系统的这种行为,因为,路由系统将只对某些片段变量使用重用值,这些片段变量在URL模式中的出现早于提供给Html.ActionLink方法的参数。如果下面这样的链接将不会被匹配:

@Html.Action(“Click me”,”List”,”Catalog”,new {color=”Aqua”},null)

   这里未提供值的片段page在URL模式中的出现晚于已提供值的color片段,因此不能使用重用值,于是这条路由将不被匹配。

   因此,这里强烈建议不要依赖与路由系统的这种行为,并应为URL模式中的所有片段变量都提供值。

指定HTML标签属性

通过提供一个匿名类型,可以为元素设置标签属性,该匿名类型的属性与所需要的标签属性相对应。如下面示例中对id标签属性的设置,并为其所在的a元素赋值了一个CSS的class:

    <div>
        <!--生成一个带有标签属性的锚点元素。class 之前使用@字符作为前缀,这是一条 C# 语言特性,它让用户能够用保留关键字作为 class 成员的名字(即以 class 作为该匿名类型的一个成员)-->
        @Html.ActionLink("This is an outgoing URL", "Index", "Home", null, new { id = "myAchorID", @class = "myCSSClass" })
    </div>

   上述这段语句将被渲染成这样的HTML:

<a class=”myCSSClass” href=”/” id=”myAnchorID”>This is an outgoing URL</a>

生成链接中的全限定URL

   前面介绍的生成的链接都是相对URL,但我们还可以使用ActionLink辅助器方法生成全限定的URL。如:

    <div>
        <!--生成权限定 URL -->
        @Html.ActionLink("This is an outgoing URL", "Index", "Home", "https", "myserver.mydomain.com", " myFragmentName", new { id = "myId" }
                          , new { id = "myAchorID", @class = "myCSSClass" })
    </div>

最终会生成这样的HTML:

<a class=”myCSSClass” href=”https://myserver.mydomain.com/Home/Index/MyId#myFragmentName” id=”myAnchorID”>This is an outgoing URL</a>

建议:在实际项目中尽可能使用相对URL,权限定URL会形成对应用程序的基础架构方式产生依赖性。

生成URL(而不是链接)

   使用Html.ActionLink辅助器方法可以生成完整的HTML的<a>元素,但如果需要,还可以使用Url.Action方法只生成URL,而不产生HTML元素。如下代码所示:

    <div>
        This is a URL:
        @Url.Action("Index", "Home", new { id = "MyId" })
    </div>

除了只生成URL外,它与Html.ActionLink方法的工作方式相同。

在动作方法中生成输出URL

有时我们需要在动作方法中输出URL,如果仅需生成URL,可以采取与在视图中同样的辅助器方法,如下:

        /// <summary>
        /// 在动作方法中生成输出 URL
        /// </summary>
        /// <returns></returns>
        public ViewResult MyActionMethod()
        {
            string myActionUrl = Url.Action("Index", new { id = "MyID" });
            string myRouteUrl = Url.RouteUrl(new { controller = "Home", action = "Index" });

            // ... 用此 URL 做些事情...
            return View();
        }

对于上面这段代码,myActionUrl 的值将是“/Home/Index/MyID”,而myRouteUrl 将为“/”。

通常,需要将客户端浏览器重定向到另一个URL。使用RedirectToAction方法可以重定向到另一个动作,该方法指示MVC框架把一条重定向指令发布给一个URL,由这个URL调用指定的动作。如:

        /// <summary>
        /// 重定向到另一个动作
        /// </summary>
        /// <returns></returns>
        public RedirectToRouteResult MyActionMethod()
        {
            return RedirectToAction ("Index");
        }

该方法的一些重载版本可以给生成的URL中片段变量指定控制器和值。

如果需要用一个URL发送一个重定向,而这个URL只是根据对象的属性生成,则还可以使用RedirectToRoute方法,如:

        /// <summary>
        /// 重定向到根据匿名类型中的属性生成的URL
        /// </summary>
        /// <returns></returns>
        public RedirectToRouteResult MyActionMethod()
        {
            return RedirectToRoute(new { controller = "Home", action = "Home", id = "MyID" });
        }

根据指定路由生成URL

下面介绍一下如何通过指定的路由生成URL或链接,当然在实际的项目中根据指定路由生成URL是不可取的,主要是因为在视图或动作方法中使用指定的路由名生成URL,等同于在建立视图或动作方法与路由自己的依赖性,而这与MVC思想是不一致的。好了,这里咱们只需要通过这种方式来理解这一过程的实现原理:

        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.MapRoute("MyRoute", "{controller}/{action}");
            routes.MapRoute("MyOtherRoute", "App/{action}", new { controller = "Home" });

        }

上面为两条路由指定了名称——MyRoute和MyOtherRoute。对路由命名的原因主要有两个:

  • 作为路由目的的一种说明
  • 便于选择特点的路由,用以生成输出URL

   由于前面路由配置已给定了路由顺序,所以,当使用下面的Html.ActionLink方法生成的链接将总是由MyRoute生成,如:@Html.ActionLink(“Click me”,”Index”,”Customer”)

   得到的结果:<a href=”/Customer/Index”>Click me</a>

可以用Html.RouteLink方法(该方法可以指定路由生成链接)覆盖这种默认路由匹配行为,这种方法需要指定一条路由(如下面粗体的“MyOtherRoute”,而斜体的粗体字“Customer”被重写了),如:

@Html.RouteLink(“Click me”,”MyOtherRoute”,”Index”,”Customer”)

结果:

<a length=”8” href=”/App/Index?Length=5”>Click me</a>

说明:就像开头说明的这种以指定路由生成URL不是明智之举,但是如果我们需要明确路由的意图时最好还是改用注释来提示。

时间: 2024-10-05 19:28:21

004_URL 路由 - 高级路由特性的相关文章

高级静态路由的浮动特性和永久特性(二)

1.说明 浮动静态路由是一种特殊的静态路由,通过配置一个比主路由的管理距离更大的静态路由,保证网络中主路由失效的情况下,提供备份路由.但在主路由存在的情况下它不出现在路由表中.主要用于ISP线路的备份.永久特性就是静态路由永久存在于路由表中,即使接口关闭. 2.模拟实验 a.实验拓扑 b.说明 从192.168.1.0/24去往2.2.2.0/24有两条线路,默认走电信线路,当电信线路故障时,自动切换到铁通线路.实现ISP的冗余. c.配置静态路由 R1(config)#ip route 2.2

openvpn高级路由技术

转:http://blog.csdn.net/dog250/article/details/6975179 目录 server模式以及点对点模式的OpenVPN OpenVPN的高级路由技术 1TAP模式虚拟网卡对源地址的检查以及路由配置思路 2TUN模式虚拟网卡对源地址的检查以及路由配置思路 3如何配置TUN模式的OpenVPN从而通过检查 4为何说网对网通透拓扑的配置很复杂 5OpenVPN的redirect-gateway选项 总结 1.server模式以及点对点模式的OpenVPN 前文

16、基于状态的iptable+高级路由(重点)

-- 基于状态的iptables 如果按照tcp/ip来划分连接状态,有12种之多 但iptables里只有4种状态:ESTABLISHED.NEW.RELATED及INVALID 这两个分类是两个不相干的定义.例如在TCP/IP标准描述下UDP及ICMP数据包是没有连接状态的,但在state模块的描述下,任何数据包都有连接状态. new(第一次) |      |-------------------->|      | |      |   established(回来)  |      |

高级静态路由之路由过滤(一)

一.说明 1.ip route命令 ip route [dest-network] [mask] {next-hop address | exit interface | ip-address]} [administrative distance] [permanent] dest-network:目的网络 mask:目的网络子网掩码 next-hop address:去往目的网络的下一跳ip地址 exit interface:去往目的网络的出站接口 administrative distanc

Redis学习第八课:Redis高级实用特性(二)

Redis高级实用特性 4.持久化机制 Redis是一个支持持久化的内存数据库,也就是说Redis需要经常将内存中的数据同步到硬盘来保证持久化.Redis支持两种持久化方式:(1).snapshotting(快照) 也是默认方式.  快照是默认的持久化方式,这种方式是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb.可以通过配置设置自动做快照持久化的方式.我们可以配置redis在n秒内如果超过m个key的修改就自动做快照. 修改配置文件redis.conf:save 9

Redis学习(6)-Redis高级实用特性

Redis高级实用特性: 1.安全性2.主从复制3.事务处理4.持久化机制5.发布订阅消息6.虚拟内存的使用 安全性: 设置客户端连接后进行任何其他指定前需要使用的密码警告:因为Redis速度相当快,所以一台比较好的服务器下一个外部的用户可以在一秒钟进行150k次的密码尝试,这意味着你需要指定非常非常强大的密码来防止暴力破解配置方法: requirepass beijing(在配置文件中配置密码) auth beijing(授权方式1) redis-cli -a beijing(授权方式2) 主

路由的几个基本概念-直连路由/网关路由/主机路由/网络路由/动态路由/静态路由/默认路由

1.动态路由/静态路由 动态路由 路由选择器自动共享路由信息 自动构造路由表,需要一个路由协议,如RIP或OSPF 静态路由 路由选择器不共享路由信息(单方向路由) 手工构造路由表 2.直连路由/网关路由(间接路由) 其区别在于,发往直连路由的设备中不但具有指明目的端的I P地址,还具有其mac地址. 当报文被发往一个间接路由时,I P地址指明的是最终的目的地,但是mac地址指明的是网关(即下一跳路由器). 3.主机路由/网络路由 直连路由和网关路由是由下一跳区分的,而主机路由和网络路由是由目的

AngularJS之基础-5 路由(定义路由、使用路由)、自定义指令(Directive)

一.定义路由 ng-view - AngularJS 支持通过在单页面上的多个视图的单页应用 - ng-view 标记只是简单地创建一个占位符 - 使用 ng-template - 创建使用script标签的HTML视图 - 使用 - 定义类型作为主模块中 ng-template 的脚本块 $routeProvider - 映射相应的HTML页面或ng-template - 附加一个控制器使用相同键的服务   - 注意: - 需要angular-route.js脚本文件的引用 二.使用路由 锚点

网络基础--静态路由+动态路由

说明:在用IP标示各个网络节点后,如果让相隔多个网络节点的两节点通信,需要"中间人"牵线,得一步一步告示某节点数据,要去对端节点一步步怎么走. 静态路由:手工配置静态路由信息,在转发具有匹配目的地址的分组时能够根据路由信息使用专线接口或下一跳IP地址进行转发. 优点:配置简单,占用系统资源少 缺点:大规模网络中配置繁琐,且缺乏灵活性,网络拓扑变更时,路由信息需要手工调整. 动态路由:利用算法和协议,分享和动态学习路由信息 优点:实时性,灵活性,精确性 缺点:资源消耗大,维护成本高 RI