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 请求并找到可响应该请求的控制器的规则

  1. 我们使用一条路由规则将请求映射到不同的控制器
  2. 我们告诉 routeBuilder 我们想要映射一个新的路由,它的名字是 Default,然后提供最重要的路由信息​​,路由模板
  3. 路由模板是一个字符串,它用于向 ASP.NET Core MVC 描述如何拆分 URL
  4. 在前面的章节中,我们添加了一个 HomeController,因此我们可以请求以下任何 URL,并且它们也将被定向到 HomeController 上的 Index 操作
    1. https://localhost:5001
    2. https://localhost:5001/Home
    3. https://localhost:5001/Home/Index
  5. 当浏览器请求 http://mysite/http://mysite/ Home 时,它将得到 HomeController 的 Index 方法的输出的内容
  6. 我们可以通过更改浏览器中的 URL 来尝试此操作。在这个例子中,它是 https:// localhost:5001/ ,可能端口号有所不同
  7. 如果我们将 /Home/Home/Index 追加到 URL 并按下 Enter 按钮,也会看到相同的结果
  8. 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 方法,然后这个请求会进入下一个中间件

关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.