ToB企服应用市场:ToB评测及商务社交产业平台

标题: ASP.NET Core MVC 从入门到精通之路由 [打印本页]

作者: 写过一篇    时间: 2023-4-14 02:53
标题: ASP.NET Core MVC 从入门到精通之路由
随着技术的发展,ASP.NET Core MVC也推出了好长时间,经过不断的版本更新迭代,已经越来越完善,本系列文章主要讲解ASP.NET Core MVC开发B/S系统过程中所涉及到的相关内容,适用于初学者,在校毕业生,或其他想从事ASP.NET Core MVC 系统开发的人员。 经过前几篇文章的讲解,初步了解ASP.NET Core MVC项目创建,启动运行,以及ASP.NET Core MVC的命名约定,创建控制器,视图,模型,接收参数,传递数据等内容,今天继续讲解ASP.NET Core MVC 路由等相关内容,仅供学习分享使用。

 
 
什么是路由?

 
路由是一种机制,主要是用于检查每一个用户请求,将用户请求映射到Action中,这一动作通过路由中间件来实现。ASP.NET Core MVC使用路由中间件来匹配传入请求的URL并将它们映射到操作(Action方法)。
 
默认路由

 
在通过模板创建ASP.NET Core MVC中,默认会添加路由中间件,并提供一种默认的路由映射规则和约束。
MapControllerRoute 用于创建单个路由。 单个路由命名为 default 路由。 大多数具有控制器和视图的应用都使用类似 default 路由的路由模板。如下所示:
  1. 1 using Microsoft.AspNetCore.Server.Kestrel.Core;
  2. 2 using System.Text.Encodings.Web;
  3. 3 using System.Text.Unicode;
  4. 4
  5. 5 var builder = WebApplication.CreateBuilder(args);
  6. 6
  7. 7 // Add services to the container.
  8. 8 builder.Services.AddControllersWithViews().AddJsonOptions(options =>
  9. 9 {
  10. 10     options.JsonSerializerOptions.Encoder = JavaScriptEncoder.Create(UnicodeRanges.All);
  11. 11 });
  12. 12
  13. 13 builder.Services.Configure<KestrelServerOptions>(options =>
  14. 14 {
  15. 15     options.AllowSynchronousIO = true;
  16. 16 });
  17. 17
  18. 18 var app = builder.Build();
  19. 19
  20. 20 // Configure the HTTP request pipeline.
  21. 21 if (!app.Environment.IsDevelopment())
  22. 22 {
  23. 23     app.UseExceptionHandler("/Home/Error");
  24. 24     // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
  25. 25     app.UseHsts();
  26. 26 }
  27. 27
  28. 28 app.UseHttpsRedirection();
  29. 29 app.UseStaticFiles();
  30. 30 //1. 添加路由中间件EndpointRoutingMiddleware
  31. 31 app.UseRouting();
  32. 32
  33. 33 app.UseAuthorization();
  34. 34
  35. 35 //2.为控制器和Action添加一种路由映射规则,包括名称,规则,约束等
  36. 36 app.MapControllerRoute(
  37. 37     name: "default",
  38. 38     pattern: "{controller=Home}/{action=Index}/{id?}");
  39. 39
  40. 40 app.Run();
复制代码
在上述代码中,创建默认路由的关键代码如下所示:
  1. 1 app.MapControllerRoute(
  2. 2     name: "default",
  3. 3     pattern: "{controller=Home}/{action=Index}/{id?}");
复制代码
其中各个属性说明:
 
默认路由示例

 
创建默认路由的简便写法,可通过以下代码替代上面的app.MapControllerRoute,如下所示:
  1. 1 //创建默认传统路由的简便写法
  2. 2 app.MapDefaultControllerRoute();
复制代码
以上是传统路由的示例。 之所以称为传统路由,是因为它为 URL 路径建立了一个约定:
此传统路由映射具有以下特点:
使用默认路由进行传统路由可以创建应用,而无需为每个操作提出新的 URL 模式,有助于简化代码。使 UI 更具可预测性。
 
多个路由

 
在实际应用中,可以设置多个路由,为某些特定的需求设置专有路由。设置多个路由,如下所示:
  1. 1 //2.为控制器和Action添加一种路由映射规则,包括名称,规则,约束等
  2. 2 app.MapControllerRoute(
  3. 3     name: "blog",
  4. 4     pattern: "blog/{*article}",
  5. 5     defaults: new { controller = "Blog", action = "Article" });
  6. 6
  7. 7 app.MapControllerRoute(
  8. 8     name: "default",
  9. 9     pattern: "{controller=Home}/{action=Index}/{id?}");
复制代码
在上述代码中,名称为blog的路由,虽然采用的是传统路由,但只用于特定操作。
在创建多个路由时,以下几点需要注意:
 
不明确操作

 
如果同一个请求有两个action都满足路由终结点的匹配,那么路由会进行如下处理:
如下代码,在请求时,会两个都满足路由匹配规则:
  1. 1 /// <summary>
  2. 2 /// 请求需要编辑的学生信息
  3. 3 /// </summary>
  4. 4 /// <param name="id"></param>
  5. 5 /// <returns></returns>
  6. 6 public IActionResult Edit(int id)
  7. 7 {
  8. 8     var student = new Student()
  9. 9     {
  10. 10         Id = 1,
  11. 11         Name = "公子小六",
  12. 12         Age = 21,
  13. 13         Sex = "男"
  14. 14     };
  15. 15     return View();
  16. 16 }
  17. 17
  18. 18 /// <summary>
  19. 19 /// 编辑后保存学生信息
  20. 20 /// </summary>
  21. 21 /// <param name="id"></param>
  22. 22 /// <param name="student"></param>
  23. 23 /// <returns></returns>
  24. 24 public IActionResult Edit(int id, Student student)
  25. 25 {
  26. 26     //保存学生
  27. 27     return View();
  28. 28 }
复制代码
那么路由中间件就会跑出异常,如下所示:

 
 在这种情况下,要解析正确的路由,需要通过Http谓词来区分,只有当请求为Post时,才会请求Edit(int id,Student student);其他请求时【一般为Get】,匹配Edit(int id)。添加Http谓词后的代码如下:
  1. 1 /// <summary>
  2. 2 /// 请求需要编辑的学生信息
  3. 3 /// </summary>
  4. 4 /// <param name="id"></param>
  5. 5 /// <returns></returns>
  6. 6 public IActionResult Edit(int id)
  7. 7 {
  8. 8     var student = new Student()
  9. 9     {
  10. 10         Id = 1,
  11. 11         Name = "公子小六",
  12. 12         Age = 21,
  13. 13         Sex = "男"
  14. 14     };
  15. 15     return View();
  16. 16 }
  17. 17
  18. 18 /// <summary>
  19. 19 /// 编辑后保存学生信息
  20. 20 /// </summary>
  21. 21 /// <param name="id"></param>
  22. 22 /// <param name="student"></param>
  23. 23 /// <returns></returns>
  24. 24 [HttpPost]
  25. 25 public IActionResult Edit(int id, Student student)
  26. 26 {
  27. 27     //保存学生
  28. 28     return View();
  29. 29 }
复制代码
 
属性路由

 
属性路由一般用于WebAPI,使用一组属性将操作直接映射到路由模板,将应用功能建模为一组资源。属性路由使用[Route(template)]标记于controller或action中,示例如下所示:
  1. 1 public class TestController : Controller
  2. 2 {
  3. 3
  4. 4     [Route("Test1")]
  5. 5     [Route("Test1/Index")]
  6. 6     [Route("Test1/Index/{id?}")]
  7. 7     public IActionResult Index(int id)
  8. 8     {
  9. 9         ViewBag.Id = id;
  10. 10         return View();
  11. 11     }
  12. 12
  13. 13     public IActionResult Test()
  14. 14     {
  15. 15         return View();
  16. 16     }
  17. 17 }
复制代码
运行程序,在浏览器中,输入网址【https://localhost:7116/Test1/Index/10】,如下所示:

 
注意:属性路由中,也可用标记:[Route("[controller]/[action]")],效果可传统路由一致。
属性路由与传统路由对比
经过以上示例,属性路由与传统路由,主要由以下几点差异:
 
保留关键字

 
在ASP.NET Core MVC项目中,会有一些关键字,作为路由参数名称,如下所示:
在 Razor 视图或 Razor 页面的上下文中保留以下关键字:
一个常见错误是使用 page 作为属性路由的路由参数。 这样做会导致与 URL 生成不一致和令人困惑的行为。错误示例如下所示:
  1. 1 public class TestController : Controller
  2. 2 {
  3. 3     [Route("/articles/{page}")]
  4. 4     public IActionResult ListArticles(int page)
  5. 5     {
  6. 6         return View(page);
  7. 7     }
  8. 8 }
复制代码
 
Http谓词和路由模板

 
在ASP.NET Core MVC项目中,具有以下几种谓词,用于区分不同的请求方式:
ASP.NET Core 具有以下路由模板:
 
混合路由:属性路由与传统路由

 
ASP.NET Core 应用可以混合使用传统路由和属性路由。 通常,对为浏览器提供 HTML 页的控制器使用传统路由,对为 API 提供服务 REST 的控制器使用属性路由。
操作既支持传统路由,也支持属性路由。 通过在控制器或操作上放置路由可实现属性路由。 不能通过传统路由访问定义属性路由的操作,反之亦然。 控制器上的任何路由属性都会使控制器中的所有操作使用属性路由。
属性路由和传统路由使用相同的路由引擎。
以上就是ASP.NET Core MVC从入门到精通之路由的全部内容,旨在抛砖引玉,一起学习,共同进步。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!




欢迎光临 ToB企服应用市场:ToB评测及商务社交产业平台 (https://dis.qidao123.com/) Powered by Discuz! X3.4