【ASP.NET Core】给路由规则命名有何用处

上一篇中老周给伙伴们介绍了自定义视图搜索路径的方法,本篇咱们扯一下有关 URL 路径规则的名称问题。在扯今天的话题之前,先补充点东东。在上一篇中设置视图搜索路径时用到三个有序参数:{2}{1}{0},分别是 Area、Controller、Action。其中说到几个特殊的视图,如_Layout.cshtml、_ViewStart.cshtml等。_Layout.cshtml 页默认放在 /Views/Shared 目录下,但,_ViewStart.cshtml 和 _ViewImports.cshtml 这两个不应该放在 Shared 目录下,一般应放到 /Views 下,这样它们可以作用于所有的视图。如果放到了 Shared 目录下,它们只对 Shared 目录中的视图起作用,而对于 Views 下的其他视图不起作用。

比如,放到 /Views 下。

Views(目录)│  _ViewImports.cshtml│  _ViewStart.cshtml│  └─Home(目录,Controller的名字)Index.cshtml(视图,Action)

其中,Home 是子目录,对应着控制器 Home,Home 中的 Index.cshtml 视图对应着 Action 名 Index。此时,_ViewStart 和 _ViewImports 中的内容会应用到 /Views 下的所有视图中(如 Index.cshtml)。

要是改为这样。

Views

    ├─Home

    │      About.cshtml

    │      Index.cshtml

    │      _ViewImports.cshtml

    │      _ViewStart.cshtml

    │      

    └─Users

            AddNew.cshtml

此时,Views 有两个子目录,Home 是一个控制器,Users 是另一个控制器,这时候,_ViewStart 和 _ViewImports 只对 Home 下面的视图起作用,对 Users 目录下的视图是不起作用的。

_ViewStart 主要用途是在所有视图文件执行之前执行,一般我们用它来设置 Layout 属性,以指定使用的布局页(相当于页面母板),这样一来,我们不需要在每个视图上都加 Layout = "xxxx" 了。_ViewImports 主要是用来引入要用到的命名空间(就是 C# 中的 using),这样你不需要在每个视图中写一堆 @using Razor 标记了。

这两个文件都是约定式的,所以你不应该随便改它的名字,_ViewImports 可以通过 RazorTemplateEngineOptions 类的 ImportsFileName 属性来修改,不过,_ViewStart 好像不能改,老周看到 asp.net core 源码中是写死了的,估计是不能改文件名的。

其实,这两个文件不应该改名,而且你改了名字也没啥用,反正功能是不变的,还是遵守约定好一些,这样人家看你的项目时也看得懂。_Layout.cshtml 文件如非必要,也不应该改名字,如果你的应用要用多个布局视图,可能建个子目录,然后每个子目录下放_Layout,这样结构清晰一些,毕竟,看到 _Layout.cshtml 就明白它是母板页了。

 

规则模板

我们都知道,在 Startup.Configure 方法中,会以此方式来指定 URL 路径规则。

            app.UseMvc(route =>{route.MapRoute("main", "{controller=Students}/{action=List}/{sid?}");route.MapRoute("edit_post", "{controller}-{action}");});

你可以添加 K 条规则,比如上面的例子,我添加了两条规则。

{controller} 和 {action} 是约定的名称,用来识别 Controller 和 Action ,所以你不要自作聪明乱来,必要有些写死了的参数才能进行 URL 分析,不然,你给个 URL http://dog.org/shopping/pay/500,那应用程序根本不知道哪一段是表示 Controller,哪一段是表示 action。

如果确定了 controller 和 action 这两个值,那么其他的参数就好分析了。

其他参数如果是可选的,可以在后面加个问号,比如 {controller}/{action}/{id?},这表示 id 的值是可选的。

上面老周添加的两个规则中,edit_post 那个其实不太规范,URL 中各段最好用 “/” 来分隔,因为 “-” 有时候是不允许用的,比如,id 参数前面就不能用,你不能写成 {controller}-{action}-{id?},要是 id 中包含了字符“-”,咋办呢?而“/”则不同,URL Encode 后不会冒出这个字符来。

所以用 / 最好,这里用 - 只是老周故意用来演示而已,URL 嘛,没必要玩花样,没意义。

 

基于 Attribute 指定的 URL 路由

在 Startup.Configure 方法中指定的 URL 路由是作用于整个应用程序的,如果想为个别控制器或个别 Action 指定路由规则,那么可以考虑使用 Attribute 的形式。

attribute 形式的路由规则和应用程序级别的规则相似,只是,在应用级别时,用大括号来包裹参数名(如 {controller}),而在 Attribute 方案中,是用中括号的,它只能用两个值:[controller]、[action]。其他参数也是用大括号。比如,[controlloer]/[action]/[id?] 会报错,你得改为 [controller]/[action]/{id?}。

RouteAttribute 既可以用于 Controller 类型,也可能用于单个 Action 方法上。我举个例子,像这样。

[Route("hello/[controller]/[action]")]

    public class SomethingController : Controller

    {

        [Route("{name?}")]

        public IActionResult SayHi(string name)

        {

            ……

        }

    }

在类上应用用的 Attribute 中,可以使用这样的 URL :http://localhost:999/hello/something/sayhi 。而在 SayHi 方法上,又用了 Route Attribute,指定了一个附加参数 name,并且是可选的。于是它可以与类上的 Route attribute 合并,变成:http://localhost:999/hello/something/sayhi/Peter。这时,字符串 Peter 会传给 SayHi 方法的 name 参数,因为,参数的名字与 Route 中的参数名是相同的,都叫 name。如果 SayHi 中的参数名不叫 name,那你得运用一下 FromRouteAttribute 了。就像这样。

        [Route("{name?}")]        public IActionResult SayHi([FromRoute(Name = "name")]string who){……}

如果你希望 URL 中给 name 传入 int 类型的值,你还可以限制它。

 [Route("{name:int}")]

其实这些约束条件对应的是 Microsoft.AspNetCore.Routing.Constraints 命名空间下面的类型。

 

Route Data

Route data 其实就是一个字典,存放的就是 URL 路径规则中参数与值的 key-value 对。这个很简单,我举个例子,你就明白了。

咱们就直接用上面那个例子吧。

[Route("hello/[controller]/[action]")]

    public class SomethingController : Controller

    {

        [Route("{name?}")]

        public IActionResult SayHi([FromRoute(Name = "name")]string who)

        {

            return Json(RouteData.Values);

        }

    }

在 SayHi 方法中,咱们把 route data 返回。

运行应用后,输入地址:http://localhost/hello/something/sayhi/Tom,得到的输出如下:

不用我解释了吧。

 

给路由命名

上面的都是 F 话,本小节才是本文的主题。我们回头看看上面老周举过例的那个 route。

            app.UseMvc(route =>{route.MapRoute("main", "{controller=Students}/{action=List}/{sid?}");route.MapRoute("edit_post", "{controller}-{action}");});

每条路由规则都会有自己的 name,为啥要命名?最直接的理由是为了唯一标识每条规则。除了此因素外,我们可以在开发过程中选择使用哪条规则,有了 name,想找出某条规则就好办了,就好比你上学的时候,老师点名,要么点姓名,要么点学号。

基于 Attribute 的路由规则也可以命名的,例如。

 [Route("hello/[controller]/[action]", Name = "prv")]

这样就把它命名为 prv 了,你还可以这样写。

  [Route("hello/[controller]/[action]", Name = "[controller]_[action]")]

这样也可以用 Controller 和 Action 的名字生成一个唯一的名字,比如 Something_SayHi。但是这种方法太动态了,好像不那么好操控,还是用一个固定的名字好一点。

要在开发的时候选择使用指定的 URL 路由,需要在 Razor 页中添加 Tag Helper,标记帮助类可以扩展 HTML 标记的某些功能。在需要使用 tag helper 的页面,或者统一在 _ViewImports.cshtml 页中加入这些指令。

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers

格式是这样的:

<类型全路径>, <程序集>

类型写在前面(包括 namespace 名),程序集名写在后面,用逗号分隔。这里用星号(*)是最爽的,它是通配符,表示引入所有 tag helper 类型。这样快捷,一行代码了事。

然后在 HTML 中你这样写。

<form method="post"

          asp-route="edit_post">

        <div class="form-group">

            <label asp-for="Name"></label>

            <input asp-for="Name" class="form-control"/>

            <span asp-validation-for="Name" class="text-danger"></span>

        </div>

        <div class="form-group">

            <label asp-for="Age"></label>

            <input asp-for="Age" class="form-control"/>

            <span asp-validation-for="Age" class="text-danger"></span>

        </div>

        <input asp-for="ID"/>

        <button type="submit" class="btn btn-dark">提交</button>

    </form>

其他代码你不用看了,只看这一句就够了:

 asp-route="edit_post"

它的意思就是使用我刚刚定义的那条规则。

 route.MapRoute("edit_post", "{controller}-{action}");

所以,在运行后就会生成这样的 HTML。

   <form method="post" action="/Students-Editdata"><div class="form-group">此处省略 1650 个字</form>          

因为我定义的规则是 {controller}-{action}的形式,所以,Controller 是 Students,Action 是 Editdata,连起来就是 Students-Editdata。

那么,这里它为什么能识别出 controller 和 action 的值呢,你看看我的代码就知道了。

public class StudentsController : Controller

    {

        readonly StudentDBContext m_context;

        // 接收依赖注入

        public StudentsController(StudentDBContext c)

        {

            m_context = c;

        }


        public IActionResult List()

        {

            var q = from s in m_context.Students

                    orderby s.ID

                    select s;


            return View(q.ToList());

        }


        /***************************************************/

        // 以下方法用于编辑页

        [HttpGet]

        public IActionResult Editdata([FromRoute(Name = "sid")] int id)

        {

            var q = from s in m_context.Students

                    where id == s.ID

                    select s;

            Student stu = q.FirstOrDefault();

            if(stu == null)

            {

                return Content("在地球上找不到此学员。");

            }

            return View(stu);

        }


        [HttpPost]

        public IActionResult Editdata(Student s)

        {

            if (ModelState.IsValid == false)

            {

                return View(s);

            }

            m_context.Students.Update(s);

            m_context.SaveChanges();

            return RedirectToAction(nameof(List));

        }

    }

定义了 Editdata 方法的重载,一个用于 get 请求,一个用于 post 请求,form 是以 post 方式提交,因此它能自动识别出 controller 和 action 的名字。

那万一,如果不是同名的呢,好办。你用 asp-route-<value> 来指定各个参数的值。比如这样

    <form method="post"asp-route="edit_post"asp-route-controller="Demo"asp-route-action="Runwork"asp-route-sid="1">

在 asp-route- 后面直接跟上路由规则参数的名称就可以了。

 

有一点要注意,asp-route 与 asp-controller、asp-action是会冲突的,如果你用了这两个标记,就不能用 asp-route 标记了,当然 asp-route-xxx 是可以用的。

好了,今天的内容就扯到这儿了,顺便把示例的代码也传上来,以供伙伴们娱乐。

https://files.cnblogs.com/files/tcjiaan/NamedRouteSample.zip

原文地址:https://www.cnblogs.com/tcjiaan/p/8439178.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/322118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringCloud Greenwich(五)之nacos、dubbo、Zuul和 gateway集成

本项目是搭建基于nacos注册中心的springcloud&#xff0c;集成dubbo框架&#xff0c;使用zuul网关和gateway网关 一、框架搭建 &#xff08;1&#xff09;项目结构 micro-service 服务提供者 zuul-gateway zuul网关 springcloud-gateway gateway网关 class-provider dubo…

P4318,bzoj2440-完全平方数【二分答案,莫比乌斯函数,容斥】

正题 题目链接: https://www.luogu.org/problem/P4318 https://www.lydsy.com/JudgeOnline/problem.php?id2440 题目大意 完全平方数只对应任意一个的正整数满足d∣n,d2∤nd\mid n,d^2\nmid nd∣n,d2∤n(也就是nnn的质因数分解后都没有次数)。 求第kkk个完全平方数 解题思路…

.NET/.NET Core中更清晰的堆栈跟踪

在基于异常的语言中&#xff0c;堆栈跟踪是用于诊断问题最重要的工具之一。在某些情况下&#xff0c;开发人员能得到的仅为一条简短的错误信息以及堆栈跟踪&#xff0c;尤其是当个人可识别信息&#xff08;PII&#xff09;约束限制了日志记录的内容时。随着任务并行库&#xff…

SpringCloud Greenwich(六)集成dubbo与openfeign的feignTargeter报错,cannot access its superinterface Targeter

一、现象 org.springframework.beans.factory.BeanCreationException: Error creating bean with name feignTargeter defined in class path resource [org/springframework/cloud/openfeign/FeignAutoConfiguration$HystrixFeignTargeterConfiguration.class]: Initializati…

bzoj2226-[Spoj5971]LCMSum【欧拉函数,GCD】

正题 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id2226 https://www.luogu.org/problem/SP5971 题目大意 求∑i1nlcm(n,i)\sum_{i1}^n lcm(n,i)i1∑n​lcm(n,i) 解题思路 ∑i1nlcm(n,i)\sum_{i1}^n lcm(n,i)i1∑n​lcm(n,i) ∑i1nnigcd(n,i)\sum_{i1}^n \fr…

一个开源的强类型客户端(.NET 中的 Open Fegin)— Rabbit Go

在做RabbitCloud&#xff08;之前是一个RPC&#xff0c;现在是一个微服务框架&#xff09;的时候往往避不开客户端代理&#xff0c;之前把这些客户端代理都算作服务框架不可缺少的一部分&#xff0c;随着后期的深入发现这些客户端代理其实可以互通&#xff0c;类似spring cloud…

SpringCloud Greenwich(七)集成dubbo先启动消费者(check=false),然后启动提供者无法自动发现注册

SpringCloud Greenwich集成dubbo先启动消费者&#xff08;checkfalse&#xff09;&#xff0c;然后启动提供者无法自动发现注册问题。 官方说明&#xff1a;修复bug的提交时间 spring-cloud-starter-dubbo 2.2.4.RELEASE之前的版本都会有先启动消费者&#xff08;checkfalse&am…

bzoj2186,P2155-[SDOI2008]沙拉公主的困惑【线性筛,欧拉函数,逆元】

正题 题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id2186 https://www.luogu.org/problem/P2155 题目大意 求∑i1n!((i,m!)1)\sum_{i1}^{n!}((i,m!)1)i1∑n!​((i,m!)1) 解题思路 因为gcd(m!,i)1⇒gcd(m!,im!)1gcd(m!,i)1\Rightarrow gcd(m!,im!)1gcd(m!,i)1…

.NET Core 实现定时抓取博客园首页文章信息并发送到邮箱

前言大家好&#xff0c;我是晓晨。许久没有更新博客了&#xff0c;今天给大家带来一篇干货型文章&#xff0c;一个每隔5分钟抓取博客园首页文章信息并在第二天的上午9点发送到你的邮箱的小工具。比如我在2018年2月14日&#xff0c;9点来到公司我就会收到一封邮件&#xff0c;是…

Linux shell echo打印不出换行

一、现象 echo打印不出换行 指令 ps aux | grep python ps aux | grep python | xargs echo 运行结果&#xff1a; 二、使用参数-e echo一样打印不出换行 ps aux | grep python | xargs echo -e 运行结果&#xff1a; 三、使用参数-e和双引号包裹占位符 echo终于可以…

jzoj6286,P4442-走格子(Portal)【BFS,SPFA】

正题 题目链接:https://www.luogu.org/problem/P4442 题目大意 一个n∗mn*mn∗m的矩阵&#xff0c;有墙。然后每次可以上下左右或者走入传传送门。当然也可以像上下左右任意一个方向发射传送门(直到碰到墙)但这并不会消耗时间。 求起点到终点的最短时间。 解题思路 首先我们…

基于Citus和ASP.NET Core开发多租户应用

Citus是基于PsotgreSQL的扩展&#xff0c;用于切分PsotgreSQL的数据&#xff0c;非常简单地实现数据“切片&#xff08;sharp&#xff09;”。如果不使用Citus&#xff0c;则需要开发者自己实现分布式数据访问层&#xff08;DDAL&#xff09;&#xff0c;实现路由和结果汇总等逻…

jzoj6287-扭动的树【区间dp】

正题 题目大意 一颗二叉查找树&#xff0c;以keyikey_ikeyi​为建值&#xff0c;以pip_ipi​为价值。然后一个节点的sumsumsum定义为这棵子树的价值之和。 要求相邻两个节点不互质的情况下所有节点的最大sumsumsum值之和。 解题思路 二叉查找树满足中序遍历的建值从小到大&a…

SpringCloud Zuul(一)之介绍

一、zuul官方简介 &#xff08;1&#xff09;什么是zuul Zuul是从设备和网站到Netflix流媒体应用程序后端的所有请求的前门。作为边缘服务应用程序&#xff0c;Zuul旨在实现动态路由&#xff0c;监视&#xff0c;弹性和安全性。它还可以根据需要将请求路由到多个Amazon Auto …

ASP.NET CORE 微服务(简化版)实战系列-没有比这性价比再高的实战课程了

ASP.NET CORE 微服务(简化版&#xff09;实战系列&#xff0c;最后1天298&#xff0c;现在注册购买再减50。作者jesse 腾飞在2.14 早上我买了他的课程后&#xff0c;他才做了下面这个活动&#xff1a;作者jesse 腾飞花了大量的时间做了一个非常好的视频教程&#xff0c;我个人也…

SpringCloud Zuul(二)之简单用法

一、引用Zuul 要将Zuul引用在项目中&#xff0c;请使用组ID为org.springframework.cloud和工件ID为的启动器spring-cloud-starter-netflix-zuul。 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix…

jzoj6288-旋转子段【优雅的暴力】

正题 题目大意 一个长度为nnn的序列。可以选择一段区间旋转&#xff0c;求使得∑i1n[aii]\sum_{i1}^n[a_ii]∑i1n​[ai​i]最大。 解题思路 现在序列中每隔一个插入一个#\##号(伪插入) 用gig_{i}gi​表示以中点为iii的序列翻转后能够对应的数字。 然后枚举中心点&#xff0c…

祝大家狗年家庭事业旺旺旺

冒泡排序&#xff0c;选择排序&#xff0c;插入排序&#xff0c;快速排序&#xff0c;堆排序&#xff0c;归并排序&#xff0c;希尔排序&#xff0c;桶排序&#xff0c;基数排序新年帮您排忧解难。有向图&#xff0c;无向图&#xff0c;有环图&#xff0c;无环图&#xff0c;完…

SpringCloud Zuul(三)之常见用法

一、route配置 &#xff08;1&#xff09;Zuul Http客户端 Zuul使用的默认HTTP客户端现在由Apache HTTP客户端而不是不推荐使用的Ribbon支持RestClient。要使用RestClient或okhttp3.OkHttpClient设置ribbon.restclient.enabledtrue或ribbon.okhttp.enabledtrue。如果要自定义…

携程Apollo(阿波罗)配置中心在.NET Core项目快速集成

.NET Core的支持文档大体上可以参考文档.Net客户端使用指南&#xff1a;https://github.com/ctripcorp/apollo/wiki/.Net%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97登录Apollo上新建App和相关的配置项&#xff0c;可以参考如下配置&#xff1a;在Nuget上…