【ASP.NET Core 基础知识】--路由和请求处理--路由概念(一)

2024-01-18 08:44:54 浏览数 (2)

在Web应用中,路由是一个至关重要的概念,它负责将用户的请求映射到相应的处理程序,以确保正确的页面或资源被呈现给用户。通过将用户请求与适当的处理程序关联起来,使得应用能够以有序和可维护的方式响应用户的操作。

一、ASP.NET Core路由基础
1.1 路由的定义和作用
  1. 路由的定义: 路由是Web应用中的一个关键概念,它负责将用户发起的HTTP请求映射到相应的处理程序,通常是控制器中的动作方法。在ASP.NET Core等框架中,路由系统会根据请求的URL和路由规则,确定执行哪个控制器的哪个动作方法来处理请求。
  2. 路由的作用:
    • 请求映射: 路由的主要作用是将传入的HTTP请求映射到应用程序中的特定处理程序。这使得应用程序能够根据用户请求的不同部分执行不同的逻辑。
    • URL解析: 路由负责解析URL,提取其中的信息以确定请求的性质。这可能包括控制器、动作方法以及其他参数。
    • RESTful设计: 在RESTful架构中,路由是实现资源的标识和操作的关键。通过定义RESTful路由,可以使Web应用程序的设计更加符合REST原则。
    • 参数传递: 路由允许从URL中提取参数,这些参数可以用于定制请求的处理方式。这包括查询字符串参数、路由值参数等。
    • 友好的URL: 路由设计的良好性可以创建友好的URL结构,这有助于用户理解和记忆URL。清晰的URL也对搜索引擎优化(SEO)有积极影响。
    • 路由约束: 路由可以定义各种约束,以确保请求满足特定的条件。这可以包括正则表达式、长度限制、范围限制等。
    • URL生成: 路由不仅仅处理输入请求,还负责生成URL。这使得在应用程序中创建链接和导航变得简单,应用程序的其他部分可以通过路由生成正确的URL。
    • 中间件支持: 路由通常与中间件一起工作,以执行与请求处理相关的其他任务,例如身份验证、授权等。
1.2 路由的主要组件

路由在Web应用中由几个主要组件构成,这些组件协同工作以确保请求被正确地映射到相应的处理程序。以下是路由的主要组件:

  1. 路由模板(Route Template): 路由模板定义了URL的结构和参数的位置。它是一个包含占位符的字符串,这些占位符表示将要从URL中提取的参数。路由模板通过一种模式来匹配传入请求的URL,从而确定如何映射到相应的处理程序。
  2. 控制器(Controller): 控制器是一个处理HTTP请求的类,负责处理与用户操作相关的逻辑。在路由中,控制器用于组织和封装相关的动作方法。每个控制器都有一个与之相关的路由。
  3. 动作方法(Action Method): 动作方法是控制器中的方法,用于执行特定的操作或响应用户的请求。路由系统将根据路由模板和请求的URL确定要执行的控制器和动作方法。
  4. 路由表(Route Table): 路由表是一个数据结构,它存储了应用程序中所有定义的路由规则。路由表中包含了每个路由的路由模板、相关的控制器和动作方法信息。当收到一个请求时,路由系统会查找路由表以确定如何映射该请求。
  5. 路由参数(Route Parameters): 路由参数是从URL中提取的值,它们填充了路由模板中的占位符。这些参数在路由系统中被传递给相应的控制器动作方法,以便动态地处理请求。
二、路由模板详解
2.1 静态路由

静态路由是一种简单直接的路由配置方式,其中路由规则是固定的,不包含动态参数。在静态路由中,URL的结构和路由模板是固定的,不随用户请求的变化而改变。

  1. 特点:
    • 固定路由规则: 静态路由的路由规则是固定的,不包含占位符或动态参数。每个URL都与特定的控制器和动作方法相对应。
    • 简单直观: 静态路由通常比较简单,易于理解和配置。它适用于那些不需要动态参数的场景。
  2. 示例: 考虑一个使用ASP.NET Core的MVC框架的简单静态路由示例:
代码语言:javascript复制
// 静态路由配置
app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "home",
        pattern: "/home",
        defaults: new { controller = "Home", action = "Index" }
    );

    endpoints.MapControllerRoute(
        name: "about",
        pattern: "/about",
        defaults: new { controller = "Home", action = "About" }
    );

    // 其他静态路由规则...
});

在上述示例中,两个静态路由规则分别映射到/home/about路径,每个路径都与指定的控制器(“Home”)和动作方法相关联。这意味着当用户访问/home时,将执行Home控制器的Index动作方法,而访问/about时将执行Home控制器的About动作方法。

Tip:静态路由适用于那些不需要考虑动态参数的场景,例如一些静态内容的展示页面。然而,在很多应用中,动态路由更为常见,因为它可以更灵活地处理各种用户请求。

2.2 参数化路由

参数化路由是一种更灵活的路由配置方式,允许在路由模板中包含占位符,以捕获和传递动态的参数。这使得可以处理各种不同形式的URL,并根据用户提供的输入动态地调整路由的行为。参数化路由主要涉及基本参数、可选参数和默认值三个方面。

  1. 基本参数: 基本参数是路由模板中的占位符,它们表示在特定位置接收用户请求中的值。这些参数将从URL中提取,并传递给相应的控制器的动作方法。
代码语言:javascript复制
// 基本参数化路由配置
endpoints.MapControllerRoute(
    name: "product",
    pattern: "/products/{productId}",
    defaults: new { controller = "Product", action = "Details" }
);

在上述示例中,{productId}是一个基本参数,表示在/products/路径后的任何值都将作为productId参数传递给Details动作方法。

  1. 可选参数: 可选参数是在基本参数的基础上加上括号并使用问号标记的形式,表示这个参数是可选的。如果用户在URL中提供了这个参数,它将被传递给动作方法;否则,将使用默认值或者为类型的默认值。
代码语言:javascript复制
// 可选参数化路由配置
endpoints.MapControllerRoute(
    name: "search",
    pattern: "/search/{keyword?}",
    defaults: new { controller = "Search", action = "Index", keyword = "" }
);

在上述示例中,{keyword?}是一个可选参数,用户可以选择在/search/路径后提供一个关键字,该关键字将传递给Index动作方法。如果用户未提供关键字,则使用默认值""

  1. 默认值: 默认值是为参数指定的固定值,当用户请求中没有提供相应参数时,将使用这些默认值。默认值通常与可选参数结合使用。
代码语言:javascript复制
// 默认值参数化路由配置
endpoints.MapControllerRoute(
    name: "category",
    pattern: "/category/{categoryId?}",
    defaults: new { controller = "Category", action = "Index", categoryId = 1 }
);

在上述示例中,{categoryId?}是一个可选参数,并且有一个默认值为1。如果用户未提供categoryId参数,将使用默认值1,否则将使用用户提供的值。 参数化路由使得应用程序能够更灵活地响应各种用户请求,并根据用户的输入动态地调整路由的行为。这对于构建更动态和可定制的Web应用程序是非常有益的。

三、控制器和动作方法
3.1 控制器的角色和作用

控制器在MVC(Model-View-Controller)架构中扮演着核心角色,负责接收用户的请求并协调相应的操作,以便正确呈现视图或执行其他逻辑。以下是控制器的主要角色和作用:

  1. 请求接收: 控制器负责接收来自用户的HTTP请求。请求可以包含用户通过浏览器、移动应用或其他客户端发送的各种信息,如URL参数、表单数据等。
  2. 协调操作: 一旦控制器接收到请求,它将协调相应的操作,这通常涉及到调用模型(Model)和/或视图(View)。控制器作为中介者,将请求传递给正确的业务逻辑或数据处理单元。
  3. 业务逻辑执行: 控制器负责执行业务逻辑,这可能包括从数据库中检索数据、更新模型状态、调用其他服务等。业务逻辑的具体实现可能会涉及到多个组件和模块。
  4. 模型操作: 控制器通过调用模型的方法来操作和管理应用程序的数据。它可以对模型进行查询、更新、删除等操作,以确保数据的一致性和有效性。
  5. 视图选择: 在MVC架构中,控制器通常负责选择合适的视图进行呈现。它决定了用户将看到什么内容,将请求的结果传递给视图进行展示。
  6. 响应构建: 控制器负责构建HTTP响应,其中包含将返回给用户的数据、视图或其他信息。这可能包括将模型数据传递给视图以生成HTML、JSON或其他格式的响应。
  7. 路由处理: 控制器与路由系统协同工作,确保将请求映射到正确的控制器和动作方法。它根据路由规则确定应该执行的操作。
  8. 状态管理: 在处理请求的过程中,控制器可能需要管理应用程序状态。这可以包括会话管理、身份验证状态、临时数据的存储等。
3.2 动作方法的定义和调用

动作方法是MVC(Model-View-Controller)架构中控制器的一部分,负责处理特定的用户请求并返回相应的结果。以下是动作方法的定义和调用的基本概念:

动作方法的定义:

  • 方法签名: 动作方法是控制器类中的公共方法,通常使用公共访问修饰符。它们的方法签名包括返回类型、方法名和可能的参数。
代码语言:javascript复制
public class MyController : Controller
{
    public IActionResult MyAction(string parameter1, int parameter2)
    {
        // 动作方法的实现
        return View();
    }
}
  • 返回类型: 动作方法的返回类型通常是IActionResult或其派生类型。IActionResult表示动作方法的执行结果,可以是视图、JSON数据、重定向等。
  • 参数: 动作方法可以接受各种参数,这些参数通常来自用户请求的数据,如查询字符串、路由参数、表单数据等。

动作方法的调用:

  • 通过URL触发: 用户请求通过URL映射到相应的控制器和动作方法。例如,用户访问/MyController/MyAction的URL,将触发MyController控制器的MyAction动作方法。
  • 通过HTML表单提交: 如果用户通过HTML表单提交了请求,表单的action属性通常指向相应的控制器和动作方法。当用户提交表单时,将触发相应的动作方法。
  • 通过JavaScript或AJAX: 使用JavaScript或AJAX可以在前端异步地触发动作方法。这通常涉及通过HTTP请求发送数据到控制器,并处理返回的结果。
  • 通过路由生成器: 在视图或其他部分中,可以使用路由生成器(UrlHelper)来生成动作方法的URL。这样可以确保在应用程序中正确生成与路由匹配的URL。
代码语言:javascript复制
// 在视图中使用路由生成器生成动作方法的URL
<a href="@Url.Action("MyAction", "MyController", new { parameter1 = "value1", parameter2 = 42 })">Link Text</a>

动作方法的调用是由ASP.NET Core框架和路由系统自动处理的,无需手动调用。系统根据用户的请求,将请求映射到相应的动作方法,并执行其逻辑,最后返回相应的结果。

3.3 控制器和动作方法的路由映射
四、路由约束
4.1 什么是路由约束

控制器和动作方法的路由映射是通过ASP.NET Core中的路由系统来实现的。路由系统负责将传入的HTTP请求映射到相应的控制器和动作方法,以便执行相应的业务逻辑。以下是控制器和动作方法的路由映射的基本概念:

  1. 控制器级别的路由映射: 在ASP.NET Core中,可以在控制器类上使用[Route]特性为整个控制器指定路由模板。这样,控制器中的所有动作方法都将遵循该路由模板。
代码语言:javascript复制
[Route("api/[controller]")]
public class MyController : Controller
{
    // GET: api/My
    [HttpGet]
    public IActionResult Index()
    {
        // ...
    }

    // GET: api/My/Details
    [HttpGet("Details")]
    public IActionResult Details()
    {
        // ...
    }
}

在上述例子中,MyController的路由模板是api/[controller],其中[controller]是一个占位符,会被替换为控制器的名称。因此,Index方法的路由是api/My,而Details方法的路由是api/My/Details

  1. 动作方法级别的路由映射: 除了在控制器级别指定路由外,还可以在单个动作方法上使用[Route]特性指定其路由模板。这样,该动作方法将覆盖控制器级别的路由。
代码语言:javascript复制
public class MyController : Controller
{
    // GET: api/Custom
    [HttpGet]
    [Route("api/Custom")]
    public IActionResult CustomAction()
    {
        // ...
    }
}

在上述例子中,CustomAction方法具有自己的路由模板api/Custom,与控制器级别的路由无关。

  1. 路由参数: 动作方法可以接受路由参数,这些参数可以从URL中提取。路由参数在路由模板中使用花括号 {} 包围。
代码语言:javascript复制
public class MyController : Controller
{
    // GET: api/Products/{id}
    [HttpGet("Products/{id}")]
    public IActionResult GetProductById(int id)
    {
        // ...
    }
}

在上述例子中,GetProductById方法接受一个名为id的路由参数,该参数从URL中提取。例如,/api/Products/42 将匹配到这个方法,并将id参数设置为 42

4.2 常见的路由约束类型

路由约束用于限制路由参数的取值范围,以确保只有符合特定条件的参数值才能匹配到相应的路由规则。在ASP.NET Core中,常见的路由约束类型包括正则表达式约束、长度约束和范围约束。

  1. 正则表达式约束: 正则表达式约束允许使用正则表达式来指定路由参数的格式,只有满足正则表达式条件的参数值才会匹配到路由。
代码语言:javascript复制
public class MyController : Controller
{
    // 匹配数字格式的id,例如:/api/Products/123
    [HttpGet("Products/{id:regex(^\d $)}")]
    public IActionResult GetProductById(int id)
    {
        // ...
    }
}

在上述例子中,id:regex(^\d )表示id参数必须是数字格式,正则表达式^\d 匹配一个或多个数字。

  1. 长度约束: 长度约束用于指定路由参数的长度范围,可以限制参数的最小长度、最大长度或者同时限制两者。
代码语言:javascript复制
public class MyController : Controller
{
    // 限制name参数的长度在3到50之间
    [HttpGet("Users/{name:length(3,50)}")]
    public IActionResult GetUserByName(string name)
    {
        // ...
    }
}

在上述例子中,name:length(3,50)表示name参数的长度必须在3到50之间。

  1. 范围约束: 范围约束用于限制路由参数的取值范围,可以限制参数的最小值、最大值或者同时限制两者。
代码语言:javascript复制
public class MyController : Controller
{
    // 限制age参数的值在18到99之间
    [HttpGet("Users/{age:range(18,99)}")]
    public IActionResult GetUserByAge(int age)
    {
        // ...
    }
}

在上述例子中,age:range(18,99)表示age参数的值必须在18到99之间。 通过使用这些路由约束,可以增强路由的灵活性和安全性,确保只有符合指定条件的参数值才会匹配到相应的路由规则。这有助于有效地过滤和验证用户输入。

五、总结

今天我详细解释了ASP.NET Core中路由的基本概念,包括静态路由、参数化路由的基本参数、可选参数、默认值,以及控制器和动作方法的定义与调用。此外,我介绍了控制器和动作方法的路由映射,包括控制器级别和动作方法级别的路由设置,以及常见的路由约束类型,如正则表达式、长度和范围约束。这些内容有助于构建灵活、可维护的ASP.NET Core应用程序。

0 人点赞