【asp.net core 系列】2 控制器与路由的恩怨情仇
0. 前言
在上一篇文章中,我们初步介绍了asp.net core,以及如何创建一个mvc项目。从这一篇开始,我将为大家展示asp.net core 的各种内容,并且尝试带领大家来挖掘其中的内在逻辑。
当然,那是以后的事情。这一篇将通过自定义一个控制器来为大家介绍asp.net core mvc 中控制器和路由的相关知识。
1. 控制器
先在Controllers目录下添加一个类,名叫:
public class DemoController
{
public string Index()
{
return "你好";
}
}
访问地址:
http://localhost:5006/demo/index
如果不出意外的话,你应该能看到网页上的"你好"两个字。
再新建一个类:
using Microsoft.AspNetCore.Mvc;
public class NoContrl : Controller
{
public IActionResult Index()
{
return Content("Test");
}
}
结合两个不常规的控制器类,让我们初窥asp.net core MVC是如何识别控制器的。这正是我之前说的,约定优于配置最好的体现。这个哲学最早也是为MVC提出来的,后来被.net framework引申到各个方面。
asp.net core mvc识别控制器,会在项目中发现 以Controller结尾的公开类或者继承自Controller的公开类,并将这些类标记为控制器。当接到用户或者界面转交的请求时,程序从请求路径中解析出控制器名称,然后寻找 <控制器>Controller 或者 <控制器> : Controller 的类。
在默认情况下,一个访问URL会在程序中解析成如下格式:
http://<HOST>:<PORT>/<Controller>/<Action>[其他参数]
在上文中,我们知道了控制器的解析规则,那么现在看一下Action的解析规则:
在DemoController中添加如下方法:
public int TestInt()
{
return 10;
}
public object TestObject()
{
return new
{
Name = "TestObject",
Age = 1
};
}
public string TestPublic()
{
return "成功访问 TestPublic";
}
protected string TestProtect()
{
return "成功访问 TestProtect";
}
private string TestPrivate()
{
return "成功访问 TestPrivate";
}
重新启动,后依次访问如下地址:
http://localhost:5006/Demo/TestInt
http://localhost:5006/Demo/TestObject
http://localhost:5006/Demo/TestPublic
http://localhost:5006/Demo/TestProtect
http://localhost:5006/Demo/TestPrivate
然后可以看到,TestInt、TestObject以及TestPublic均能正常访问,但TestProtect和TestPrivate都提示找不到网页或无法访问。
可以看到,对于程序而言,Action就是控制器类里的公开类方法,与方法的返回值无关。也就是说,程序会找到 XXXController 或者名为XXX但继承了Controller的类作为XXX的控制器,然后继续在这个类里寻找到Action,如果没有找到就会返回404的请求。
2. 路由
在第一节中,我们介绍了一下asp.net core mvc如何寻找控制器和Action,那这一节将介绍程序如何从请求链接中解析出控制器和Action的名称,也就是路由映射。
路由(Routing)负责匹配传入的HTTP请求,然后将这些请求发送给应用的可执行终结点。终结点是应用的可执行请求处理代码单元,也就是我们控制器里的方法(Action)。
2.1 路由的配置
对于所有的asp.net core模板都包括生成在代码中的路由。通常,我们要求路由在Startup.Configure方法中进行配置。
注意,Startup类里有且只有一个Configure方法,不能出现其重载版本。
该方法的声明一般情况如下:
public void Configure(IApplicationBuilder app, IWebHostEnvironment env);
如果想要设置路由,需要先注明项目启用路由:
app.UseRouting();
然后使用如下方法配置路由:
app.UseEndpoints(endpoints =>
{
// 配置路由
});
通常对于mvc项目而言,我们一般使用如下方式配置路由:
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
这行代码的意思是:创建一个名字为 default 的映射控制器的路由,映射规则为 {controller}/{action}/{id?},也就是第一个为控制器,第二个为Action,第三个是ID,其中ID可以不存在,当Action无法从请求地址中解析出来时默认为Index,控制器默认为Home。
通过这个解析,我们可以得知 我们之前访问的
http://localhost:5000/
是哪个控制器里的什么方法来处理了——HomeController.Index。
那么我们修改一下HomeController.Index来验证一下,我们理解是否有误:
public IActionResult Index()
{
return View();
}
// 修改为
public IActionResult Index()
{
return Content("测试");
}
重新运行程序,访问
http://localhost:5000/
然后看到页面出现:测试字样,可以看到路由系统自动为我们补全了控制器名和action名。如果方法中出现参数,则自动按照参数名1=值1&参数名2=值2这种形式查看参数。Id为特殊的,会自动按照目录其映射。所以:
http://localhost:5000/控制器1/方法1/id值
http://localhost:5000/控制器1/方法1?id=id值
是一个请求链接。
2.2 添加路由配置
那么,我们回过头来看一下声明路由的方法:
public static ControllerActionEndpointConventionBuilder MapControllerRoute(this IEndpointRouteBuilder endpoints, string name, string pattern, object defaults = null, object constraints = null, object dataTokens = null);
默认情况下,我们不会设置 defaults、constraints、dataTokens,这三个参数都有含义,这里不对后两个做介绍,简单介绍一下第一个:
在路由配置的方法里,添加以下内容:
endpoints.MapControllerRoute(
name : "test",
pattern: "DemoTest/{action=Index}/{id?}",
defaults : new
{
Controller = "Demo",
});
至此,我们没有创建名为DemoTest的控制器,但是我们在访问:
http://localhost:5006/DemoTest
仍然能得到响应,而且控制器被解析为Demo。
这就是defaults的意义,路由在解析的时候,系统会把defaults中的值自动填充到路由连接中没有设置的值里。
当我们设置多个路由的时候,路由系统会优先尝试匹配最容易解析的配置。比如说,当我们访问:
http://localhost:5000/DemoTest/
的时候,路由系统会优先从名为test的配置表中解析,只有当无法从这里找到时才会从其他路由中解析。
3. 总结
这一篇我们简单介绍了控制器与路由映射,可以访问我们自己添加的路由。在开发中,通常情况下,创建的控制器都是以Controller结尾并继承Controller类。这是因为Controller类有很多有用的属性和方法供我们使用,以Controller结尾是为了统一规则,可以让我们一眼看出哪些是控制器。
更多内容烦请关注我的博客《高先生小屋》

【asp.net core 系列】2 控制器与路由的恩怨情仇的更多相关文章
- asp.net core 系列 8 Razor框架路由(下)
三.页面路由操作约定 接着上篇讲asp.net core 系列 7 Razor框架路由.在上篇继续第三节 "页面路由操作约定" 的最后一小节 AddPageRoute . 3.3. ...
- asp.net core 系列 7 Razor框架路由(上)
一.概述 在上二篇中,主要是介绍了asp.net core mvc中路由的使用,这篇继续介绍路由在ASP.NET Core Razor中的使用.Razor Pages应该使用默认的传统路由,从应用程序 ...
- asp.net core 系列 6 MVC框架路由(下)
一.URL 生成 接着上篇讲MVC的路由,MVC 应用程序可以使用路由的 URL 生成功能,生成指向操作的 URL 链接. 生成 URL 可消除硬编码 URL,使代码更稳定.更易维护. 此部分重点介绍 ...
- asp.net core 系列 5 MVC框架路由(上)
一. 概述 介绍asp.net core路由时,我初步想了下,分几篇来说明. 路由的知识点很多,参考了官方文档提取出一些重要的知识点来说. 在ASP.NET Core中是使用路由中间件来匹配传 ...
- 【asp.net core 系列】3 视图以及视图与控制器
0.前言 在之前的几篇中,我们大概介绍了如何创建一个asp.net core mvc项目以及http请求如何被路由转交给对应的执行单元.这一篇我们将介绍一下控制器与视图直接的关系. 1. 视图 这里的 ...
- 【asp.net core 系列】4. 更高更强的路由
0. 前言 在之前我们介绍了请求通过路由寻找到控制器,以及控制器与视图的数据流转.那么,我们回过头来,再看看路由的一些其他用法. 1. 路由属性(Route Attribute) 按照英文的直接翻译, ...
- 【目录】asp.net core系列篇
随笔分类 - asp.net core系列篇 asp.net core系列 68 Filter管道过滤器 摘要: 一.概述 本篇详细了解一下asp.net core filters,filter叫&q ...
- 基于ASP.NET Core 3.x的端点路由(Endpoint Routing)实现控制器(Controller)和操作(Action)分离的接口服务
本文首发于 码友网 -- <基于ASP.NET Core 3.x的端点路由(Endpoint Routing)实现控制器(Controller)和操作(Action)分离的接口服务> 前言 ...
- asp.net core系列 40 Web 应用MVC 介绍与详细示例
一. MVC介绍 MVC架构模式有助于实现关注点分离.视图和控制器均依赖于模型. 但是,模型既不依赖于视图,也不依赖于控制器. 这是分离的一个关键优势. 这种分离允许模型独立于可视化展示进行构建和测试 ...
随机推荐
- ssm整合后打印日志查看执行sql语句
mybatis.xml <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configura ...
- layui里面的layer模块弹窗,强制居中的方法!!!
每次调用layer弹窗做动态展示的时候,只要内容不固定或者需要二次渲染 比如layui.form.render()进行渲染的时候 由于弹窗已经出来了,只是content部分的结构改变了宽度或者高度,l ...
- Javascript模块化编程-require.js
转自:https://www.cnblogs.com/digdeep/p/4607131.html Javascript模块化编程(一):模块的写法 随着网站逐渐变成"互联网应用程序&quo ...
- Mysql 常用函数(10)- strcmp 函数
Mysql常用函数的汇总,可看下面系列文章 https://www.cnblogs.com/poloyy/category/1765164.html strcmp 的作用 比较两个字符串的顺序是否完全 ...
- 07JAVA基础面向对象-继承/多态
一.继承 1.概念 子类的共性 重用现有类并在此基础上进行扩展 public class 子类 extends 父类{} 2.继承中的成员访问 成员变量 成员方法 局部->本类中成员变量-> ...
- 快速了解pandas
pandas主要就下面两方面:(只要稍微了解下面两点,那你就会用了) 1.两种数据结构(Series和DataFrame) 2.对这两种数据进行处理(主要是对DataFrame处理) -------- ...
- tp5参数传入
把应用配置文件中的url_param_type参数的值修改如下: // 按照参数顺序获取 'url_param_type' => 1, 现在,URL的参数传值方式就变成了严格按照操作方法的变量定 ...
- layui的layer.msg,form提交
layer.msg('提示文字',{shift:1,time:2000},function(){ location.reload();});其中shift是提示框的动画样式,-1为无动画form.on ...
- 【雕爷学编程】Arduino动手做(5)---热敏温度传感器模块
37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器模块,依照实践(动手试试)出真知的理念,以学习和交流为目的,这里准备逐 ...
- mysql小白系列_05 日常操作
mysql启动/关闭 my.cnf的调用顺序 [root@docker02 bin]# ./mysql --help Default options are read from the followi ...