ASP.NET Core 路由
前两章节中,我们提到 ASP.NET Core 支持 MVC 开发模式,同时也给大家详细解释了 MVC 设计模式和 ASP.NET Core 中的 MVC 设计模式
MVC 框架中,我们有三个组件,每个组件都专注于特定部分的工作。 为了使所有这些工作,我们需要找到一种方法将这些 HTTP 请求发送到正确的控制器。 在 ASP.NET Core MVC 中,这个过程称为路由。 路由是指导 HTTP 请求到控制器的过程
路由
现在,我们来了解如何将请求路由到不同的控制器
首先,ASP.NET Core 中间件需要一个方法来确定给定的 HTTP 请求是否应该发送给控制器进行处理,我们将这个过程称之为路由匹配
MVC 中间件将根据我们提供的 URL 和一些配置信息做出此决定
本章中,我们将定义这些配置信息,或者当我们添加 MVC 中间件时,可以在 Startup.cs
中说明路由信息
这种方法通常被称为基于约定的路由。
以下代码是常规路由的代码片段
routeBuilder.MapRoute("Default", "{controller=Home}/{action=Index}/{id?}");
上面的代码中,我们定义了一个路由正则,告诉 MVC 如何查看 URL 并找到控制器名称和操作名称,其中控制器是 C#
类,操作是该类上的公共方法
前面几章节中,我们已经在应用程序中创建了一个控制器 ( HomeController
) ,它是一个 C#
类,不需要从基类派生或实现接口或具有任何特殊属性。 它是一个纯 C#
类,名称为 HomeController
,它包含返回字符串的 Index()
方法
using System; namespace HelloWorld.Controllers { public class HomeController { public HomeController() { } public string Index() { return "你好,世界! 此消息来自 HomeController..."; } } }
这里,我们回到路由上来,我们将重点关注路由到控制器,我们也将尝试理解路由如何工作
现在,我们回到 Startup
类,将 MVC
中间件配置到我们的应用程序中。然后在 Configure
方法中,使用方法 UseMvcWithDefaultRoute()
public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseFileServer(); app.UseMvcWithDefaultRoute(); }
app.UseMvcWithDefaultRoute()
给了我们一个默认的路由规则,允许我们访问 HomeController
路由规则
当然了,接下来我们不使用 app.UseMvcWithDefaultRoute()
,而是使用 UseMvc()
,然后在私有方法 ConfigureRoute()
处配置路由
以下是按照这种思路的 Startup.cs
的完整代码
using System; using System.IO; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Configuration; namespace HelloWorld { public class Startup { public Startup() { var builder = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("AppSettings.json"); Configuration = builder.Build(); } public IConfiguration Configuration { get; set; } // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 public void ConfigureServices(IServiceCollection services) { services.AddMvc(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IHostingEnvironment env) { if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseFileServer(); app.UseMvc(ConfigureRoute); app.Run(async (context) => { var msg = Configuration["message"]; await context.Response.WriteAsync(msg); }); } private void ConfigureRoute(IRouteBuilder routeBuilder) { //Home/Index routeBuilder.MapRoute("Default", "{controller}/{action}/{id?}"); } } }
在 ConfigureRoute()
方法中,我们可以配置路由,也许你已经注意到了,该方法必须使用 IRouteBuilder
类型的参数
路由的目标是描述 ASP.NET Core MVC 用于处理 HTTP 请求并找到可响应该请求的控制器的规则
- 我们使用一条路由规则将请求映射到不同的控制器
- 我们告诉 routeBuilder 我们想要映射一个新的路由,它的名字是
Default
,然后提供最重要的路由信息,路由模板 - 路由模板是一个字符串,它用于向 ASP.NET Core MVC 描述如何拆分 URL
- 在前面的章节中,我们添加了一个
HomeController
,因此我们可以请求以下任何 URL,并且它们也将被定向到 HomeController 上的 Index 操作- https://localhost:5001
- https://localhost:5001/Home
- https://localhost:5001/Home/Index
- 当浏览器请求
http://mysite/
或http://mysite/ Home
时,它将得到 HomeController 的 Index 方法的输出的内容 - 我们可以通过更改浏览器中的 URL 来尝试此操作。在这个例子中,它是
https:// localhost:5001/
,可能端口号有所不同 - 如果我们将
/Home
或/Home/Index
追加到 URL 并按下 Enter 按钮,也会看到相同的结果 - id 末尾的问号表示该参数是可选的。换句话说,ASP.NET Core MVC 在这里不需要看到某种类型的 id,可能是一个数字,也可能是一个字符串或 GUID
现在,我们重启应用程序,然后刷新浏览器,我们将获得以下输出
我们只看到了从 app.Run()
中间件输出的消息,得到此消息的原因是虽然 MVC 中间件看到了该 URL。 但这是对网站根目录的请求,网址中没有找到控制器名称或操作名称。
于是 Mvc 中间件放弃了处理该请求并将请求传递给下一个中间件,也就是 app.Run()
代码。
与默认的路由模板不同,我们指定的路由模板非常安静...
安静这个词,非常好
默认的路由模板,如果找不到控制器和操作名称,则会使用一些默认值。
如果请求的是网站的根目录,则默认控制器名称将是 Home
。
我们可以根据需要将其更改为任何其它控制器,且默认操作名称可以是 Index
。
如果需要,也可以更改默认操作,如下面的程序所示
private void ConfigureRoute(IRouteBuilder routeBuilder) { //Home/Index routeBuilder.MapRoute("Default", "{controller=Home}/{action=Index}/{id?}"); }
如果请求的是网站的根目录,MVC 中间件不会看到 URL 的控制器/操作类型,但它可以使用这些默认值。
现在,我们保存 Startup.cs
文件并将浏览器定向到到网站的根目录,输出结果如下
现在,我们可以看到控制器的响应,我们也可以访问 / home
,它会调用默认的动作,也就是 Index
。我们也可以跳转到 /home/index
,MVC 会将控制器名称和操作名称从 URL 中提取出来
添加一个控制器 AboutController
现在,我们添加另一个控制器并将其命名为 AboutController
目录结构如下
内容如下
我们添加一些简单的动作,返回字符串,完整代码如下
using System; namespace HelloWorld.Controllers { public class AboutController { public AboutController() { } public string Phone() { return "+10086"; } public string Country() { return "中国"; } } }
在这个控制器中,我们可以看到两种操作方法:Phone()
和 Country()
。
我们稍后会添加一些花哨的 HTML。
但现在,我们先保存文件,然后访问 /about/phone
,显示如下
我们可以看到输出了电话号码 +10086
,如果我们访问 /about/country
,则显示如下
可以看到输出了 中国
,但如果我们访问 /about
,那么它将再次通过中间件 app.Run()
,我们将看到以下页面
看到这个页面,是因为 ASP.NET Core MVC 转到 AboutController,但没有找到指定的操作。所以它默认使用 Index,并且这个控制器没有 Index 方法,然后这个请求会进入下一个中间件