热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

asp.netcore系列5MVC框架路由(上)

一.概述介绍asp.netcore路由时,我初步想了下,分几篇来说明。 路由的知识点很多,参考了官方文档提取出一些重要的知识点来说。  在ASP.NETCore中是使用路由中间件来

一. 概述

  介绍asp.net core路由时,我初步想了下,分几篇来说明。  路由的知识点很多,参考了官方文档提取出一些重要的知识点来说。    在ASP.NET Core中是使用路由中间件来匹配传入请求的 URL 并将它们映射到操作(action方法)。路由是在程序启动时进行传统路由或属性路由定义。 路由描述如何将 URL 路径与操作相匹配。 它还用于在响应中生成送出的 URL(用于链接)。

  路由操作既支持传统路由,也支持属性路由。也可混合使用。通常传统路由用于为浏览器处理 HTML 页面的控制器。属性路由用于处理 web API 的控制器。


  1.1设置路由中间件

要使用传统路由,必须在UseMVC中间件中配置实现IRouteBuilder接口,在asp.net core mvc 2.2 框架下,应用程序Startup的Configure 方法中,默认路由设置如下:

app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{cOntroller=Home}/{action=Index}/{id?}");
});

在对 UseMvc调用中,MapRoute 用于创建单个路由,亦称 default 路由。 大多数 MVC 应用使用带有模板的路由。对于default路由简便的方法可以使用:

app.UseMvcWithDefaultRoute();

  

    UseMvc 和 UseMvcWithDefaultRoute 可向中间件管道添加 RouterMiddleware 的实例。 MVC 不直接与中间件交互,而是使用路由来处理请求。 MVC 通过 MvcRouteHandler 实例连接到路由。
    UseMvc 不直接定义任何路由,它向属性路由的路由集合添加占位符{cOntroller=Home}/{action=Index}/{id?} 。通过重载 UseMvc(Action) 则允许用户添加自己的路由,并且还支持属性路由。

  


 1.2 传统路由

 传统路由是:具有描述性的路由方案,这样URL具有可读性。传统路由格式:{cOntroller=Home}/{action=Index}/{id?}这样的url路径是设定了一个约定: 第一段映射到控制器名称, 第二段映射到操作名称,第二段映射到可选ID。

 

 (1) 使用默认路由:  

routes.MapRoute("default", "{cOntroller=Home}/{action=Index}/{id?}");

使用此默认路由时: url路径/Products/List 将映射到程序ProductsController(控制器).List(action)中。 url路径/Blog/Article/17将映射到程序BlogController(控制器).Article(action)中。

 (2) 多个路由:

通过添加对 MapRoute 的多次调用,可以在 UseMvc 内添加多个路由。 这样做可以定义多个约定,或添加专用于特定操作的传统路由,比如:

app.UseMvc(routes =>
  {
   routes.MapRoute("blog", "blog/{*article}",
defaults: new { cOntroller= "Blog", action = "Article" });
  routes.MapRoute("default", "{cOntroller=Home}/{action=Index}/{id?}");
  });

  这里的blog路由是一个专用的传统路由,这表示blog使用传统路由系统,但专用于特定的操作,也就是对于BlogController控制器的Article操作,此专用路由将始终映射。对于多个路由的路由集合会进行排序,并按添加顺序进行处理,因此,在此示例中,将先尝试 blog 路由,再尝试 default 路由。

 (3)  action操作的区分

 在处理url请求时,当通过路由匹配到一个控制器内两项相同的action名称时,mvc必须进行区分,以选择最佳候选项,否则会引发异常(AmbiguousActionException)。

public class ProductsController : Controller
{
public IActionResult Edit(int id) { ... }
[HttpPost]
public IActionResult Edit(int id, Product product) { ... }
}

此Products控制器定义了二项操作,这两项操作均与 URL 路径的 /Products/Edit/17 匹配相同。解决方案是将要提交的action加上 Http 谓词为 POST。这样post过来时,就会选择Edit(int, Product)


  1.3 属性路由

    通过在控制器(Controller)或操作(Action)上放置路由可实现属性路由。 不能通过传统路由访问定义属性路由的操作,反之亦然。 控制器上的任何路由属性,都会使控制器中的所有操作使用属性路由。

    属性路由使用一组属性将action直接映射到路由模板。在下面的示例中,Configure 方法使用 app.UseMvc();,不传递任何路由。 HomeController 将匹配一组 URL,这组 URL 与默认路由 {cOntroller=Home}/{action=Index}/{id?} 匹配的 URL 类似:

    当去掉default默认路由模板后,只使用app.UseMvc()时。运行程序时,页面报404错误:找不到 localhost 的网页。

app.UseMvc();

    (1) 属性路由基本使用   

    如果定义了属性路由的操作,此时就是启动属性路由功能。Home控制器的属性路由示例如下:

public class HomeController : Controller
{
[Route("")]
[Route("Home")]
[Route("Home/Index")]
public IActionResult Index()
{
return View();
}
}

    在index的action上加[Route("")]属性路由。 浏览器可以使用下面三种url来访问,也是程序启动时的默认加载页面:

      http://localhost:30081/

      http://localhost:30081/Home/

      http://localhost:30081/Home/index

(2) 属性路由精确控制

属性路由需要更多输入来指定路由;传统的默认路由处理路由的方式则更简洁。 但是,属性路由允许(并需要)精确控制应用于每项操作的路由模板。下面示例是精确控制每项操作的路由模板,比如url访问/home/index时,即是调用MyIndex的action方法。

public class MyDemoController : Controller
{
[Route("")]
[Route("Home")]
[Route("Home/Index")]
public IActionResult MyIndex()
{
return View("Index");
}
}

 1.4 使用 Http[Verb] 属性的属性路由

属性路由还可以使用 Http[Verb] 属性,比如 HttpPostAttribute。 所有这些属性都可采用路由模板。 此示例展示,同一路由模板匹配的两项操作:

[HttpGet("/products")]
public IActionResult ListProducts()
{
// ...
}
[HttpPost("/products")]
public IActionResult CreateProduct(...)
{
// ...
}

    当 Http 谓词为 GET 时将执行ProductsApi.ListProducts 操作, 当 Http 谓词为 POST 时将执行 ProductsApi.CreateProduct。生成 REST API 时,很少会在操作方法上使用 [Route(...)]。 建议使用更特定的 Http*Verb*Attributes 来明确 API 所支持的操作。 REST API 的客户端需要知道映射到特定逻辑操作的路径和 Http 谓词。

    例如下面一个web api访问路由,使用Http*Verb*Attributes 来明确定义如下:

public class ProductsApiController : Controller
{
[HttpGet("/products/{id}", Name = "Products_List")]
public IActionResult GetProduct(int id) { ... }
}

  上面定义只有针对如访问url如: /products/3(而非 /products)之类的 URL才会执行 ProductsApi.GetProduct(int) 操作。


 1.5 路由合并

    若要使属性路由减少重复,可将控制器Controller上的路由属性与各个操作Action上的路由属性合并。 控制器上定义的所有路由模板均作为操作上路由模板的前缀。 在控制器上放置路由属性会使控制器中的所有操作都使用属性路由。

    下面是一个web api的路由合并,访问Get的方法的访问路径为: http://localhost:30081/api/Products/1

[Route("api/Products")]
public class ProductsApiController : Controller
{
// GET api/values/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
}

下面是一个控制器的路由合并。访问index页面的访问路径为: http://localhost:30081/home/index

[Route("Home")]
  public class HomeController : Controller
  {
[Route("")] // Combines to define the route template "Home"
[Route("Index")] // Combines to define the route template "Home/Index"
[Route("/")] // Doesn't combine, defines the route template ""
public IActionResult Index()
{
//...
}
  }

 1.6 指定属性路由参数约束

[HttpGet("Home/{id:int}",Name = "Pri")]
public IActionResult Privacy(int id)
{
return View();
}

如果输入非整数类型的参数,浏览器提示:找不到与以下网址对应的网页:http://localhost:30081/home/dd


   1.7 自定义路由属性

    该框架中提供的所有路由属性([Route(...)]、[HttpGet(...)] 等)都可实现 IRouteTemplateProvider接口。 当应用启动时,MVC 会查找控制器类和操作方法上的属性,并使用可实现 IRouteTemplateProvider的属性生成一组初始路由。

    下面使用IRouteTemplateProvider 来定义自己的路由属性。每个 IRouteTemplateProvider 都允许定义一个包含自定义路由模板、顺序和名称的路由:

public class MyApiControllerAttribute : Attribute, IRouteTemplateProvider
{
//实现接口的三个属性,这里的[controller]是一个标记替换。
public string Template => "api/[controller]/{action}/{id?}";
public int? Order { get; set; }
public string Name { get; set; }
}
public class ProductsApiController : Controller
{
// GET api/values/5
// [HttpGet("{id}")]
[MyApiController()]
public string Get(int id)
{
return "value";
}
}

通过访问url: http://localhost:30081/api/ProductsApi/get/1 来调用get方法。

参考文献

  官方资料:asp.net core routing


推荐阅读
  • 使用这个技巧要达到的目标:一般来说,模型和控制器你都不会有相同的类名字。让我先创建一个取名为post的model。classPostextendsModel{}现在 ... [详细]
  • 一、路由首先需要配置路由,就是点击good组件进入goodDetail组件配置路由如下{path:goodDetail,component:goodDetail}同时在good组件中写入如下点击事件,路由中加入 ... [详细]
  • 使用nodejs爬取b站番剧数据,计算最佳追番推荐
    本文介绍了如何使用nodejs爬取b站番剧数据,并通过计算得出最佳追番推荐。通过调用相关接口获取番剧数据和评分数据,以及使用相应的算法进行计算。该方法可以帮助用户找到适合自己的番剧进行观看。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 本文详细介绍了PHP中与URL处理相关的三个函数:http_build_query、parse_str和查询字符串的解析。通过示例和语法说明,讲解了这些函数的使用方法和作用,帮助读者更好地理解和应用。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • MVC设计模式的介绍和演化过程
    本文介绍了MVC设计模式的基本概念和原理,以及在实际项目中的演化过程。通过分离视图、模型和控制器,实现了代码的解耦和重用,提高了项目的可维护性和可扩展性。详细讲解了分离视图、分离模型和分离控制器的具体步骤和规则,以及它们在项目中的应用。同时,还介绍了基础模型的封装和控制器的命名规则。该文章适合对MVC设计模式感兴趣的读者阅读和学习。 ... [详细]
  • 本文介绍了MVP架构模式及其在国庆技术博客中的应用。MVP架构模式是一种演变自MVC架构的新模式,其中View和Model之间的通信通过Presenter进行。相比MVC架构,MVP架构将交互逻辑放在Presenter内部,而View直接从Model中读取数据而不是通过Controller。本文还探讨了MVP架构在国庆技术博客中的具体应用。 ... [详细]
  • Asp.net Mvc Framework 七 (Filter及其执行顺序) 的应用示例
    本文介绍了在Asp.net Mvc中应用Filter功能进行登录判断、用户权限控制、输出缓存、防盗链、防蜘蛛、本地化设置等操作的示例,并解释了Filter的执行顺序。通过示例代码,详细说明了如何使用Filter来实现这些功能。 ... [详细]
  • 本文介绍了ASP.NET Core MVC的入门及基础使用教程,根据微软的文档学习,建议阅读英文文档以便更好理解,微软的工具化使用方便且开发速度快。通过vs2017新建项目,可以创建一个基础的ASP.NET网站,也可以实现动态网站开发。ASP.NET MVC框架及其工具简化了开发过程,包括建立业务的数据模型和控制器等步骤。 ... [详细]
  • 【前端工具】nodejs+npm+vue 安装(windows)
    预备先看看这几个是干嘛的,相互的关系是啥。nodejs是语言,类比到php。npm是个包管理,类比到composer。vue是个框架&# ... [详细]
  • Vue基础一、什么是Vue1.1概念Vue(读音vjuː,类似于view)是一套用于构建用户界面的渐进式JavaScript框架,与其它大型框架不 ... [详细]
author-avatar
涛升一舅_250
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有