在上一篇文章中,咱们初步介绍了asp.net core,以及如何建立一个mvc项目。从这一篇开始,我将为你们展现asp.net core 的各类内容,而且尝试带领你们来挖掘其中的内在逻辑。mvc
固然,那是之后的事情。这一篇将经过自定义一个控制器来为你们介绍asp.net core mvc 中控制器和路由的相关知识。app
先在Controllers目录下添加一个类,名叫:asp.net
public class DemoController
{
public string Index()
{
return "你好";
}
}
访问地址:ide
http://localhost:5006/demo/index
若是不出意外的话,你应该能看到网页上的"你好"两个字。测试
再新建一个类:ui
using Microsoft.AspNetCore.Mvc;
public class NoContrl : Controller
{
public IActionResult Index()
{
return Content("Test");
}
}
结合两个不常规的控制器类,让咱们初窥asp.net core MVC是如何识别控制器的。这正是我以前说的,约定优于配置最好的体现。这个哲学最先也是为MVC提出来的,后来被.net framework引伸到各个方面。this
asp.net core mvc识别控制器,会在项目中发现 以Controller结尾的公开类或者继承自Controller的公开类,并将这些类标记为控制器。当接到用户或者界面转交的请求时,程序从请求路径中解析出控制器名称,而后寻找 <控制器>Controller 或者 <控制器> : Controller 的类。spa
在默认状况下,一个访问URL会在程序中解析成以下格式:.net
http://<HOST>:<PORT>/<Controller>/<Action>[其余参数]
在上文中,咱们知道了控制器的解析规则,那么如今看一下Action的解析规则:code
在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的请求。
在第一节中,咱们介绍了一下asp.net core mvc如何寻找控制器和Action,那这一节将介绍程序如何从请求连接中解析出控制器和Action的名称,也就是路由映射。
路由(Routing)负责匹配传入的HTTP请求,而后将这些请求发送给应用的可执行终结点。终结点是应用的可执行请求处理代码单元,也就是咱们控制器里的方法(Action)。
对于全部的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值
是一个请求连接。
那么,咱们回过头来看一下声明路由的方法:
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的配置表中解析,只有当没法从这里找到时才会从其余路由中解析。
这一篇咱们简单介绍了控制器与路由映射,能够访问咱们本身添加的路由。在开发中,一般状况下,建立的控制器都是以Controller结尾并继承Controller类。这是由于Controller类有不少有用的属性和方法供咱们使用,以Controller结尾是为了统一规则,可让咱们一眼看出哪些是控制器。