[Route("Store")] [Route("[controller]")] public class BlogController : Controller { [HttpGet("GetAll")]//匹配 Get Blog/GetAll和 Store/GetAll [HttpPost("Set")]//匹配 Post Blog/Set和 Store/Set public ActionResult GetAll() { return View(); } }
虽然使用多个路由到一个操作看起来很强大,但最好还是保持URL的空间简单和定义明确。使用多个路由到操作上仅仅在特殊需要的时候,比如支持多个客户端。
8.使用IRouteTemplateProvider自定义路由特性
所有框架提供的路由特性([Route(...) ] ,[HttpGet(...)]等)都实现了 IRouteTemplateProvider 接口。当程序启动时,MVC查找控制器类和操作方法上都实现 IRouteTemplateProvider 接口的特性来构建储时路由集合。
可以通过实现 IRouteTemplateProvider 来定义自己的路由特性。每个 IRouteTemplateProvider 都允许定义使用自定义路由模板,顺序以及名称的单一路由:
public class MyApiControllerAttribute:Attribute, IRouteTemplateProvider { public string Template => "api/[controller]"; public int? Order { get; set; } public string Name { get; set; } }
当 [MyApiController] 特性被应用时,会自动设置Template 为 api/[controller] 。
9.使用应用程序模型来自定义特性路由
应用程序模型时启动时创建的对象模型,其中包含MVC用于路由和执行操作的所有元数据。应用程序模型包括从路由特性收集的所有数据(通过 IRouteTemplateProvider)。我们可以编写约定以在启动时修改应用程序模型为自定义路由行为。
public class NamespaceRoutingConvention:IControllerModelConvention { private readonly string _baseNamespace; public NamespaceRoutingConvention(string baseNamespace) { _baseNamespace = baseNamespace; } public void Apply(ControllerModel controller) { var hasRouteAttributes = controller.Selectors.Any(selector => selector.AttributeRouteModel != null); if (hasRouteAttributes) { //此控制器自定义了一些路由,因此将其视为覆盖 return; } // 使用命名空间和控制器来推断控制器的路由 // // Example: // // controller.ControllerTypeInfo -> "My.Application.Admin.UsersController" // baseNamespace -> "My.Application" // // template => "Admin/[controller]" // // 这使得你的路由大致与你的项目结构一致 // var namespc = controller.ControllerType.Namespace; var template = new StringBuilder(); template.Append(namespc,_baseNamespace.Length+1,namespc.Length- _baseNamespace.Length-1); template.Replace('.','https://www.jb51.net/'); template.Append("/[controller]"); foreach (var selector in controller.Selectors) { selector.AttributeRouteModel = new AttributeRouteModel() { Template = template.ToString() }; } } }
这部分怎么使用,个人还是不是很清楚,这里只是记录了官方文档,有哪位知道可以告诉以下小弟。
10.URL生成
MVC应用程序可以使用路由URL的生成特性来生成URL链接到操作。生成URL可以消除硬编码URL,使代码更加健壮和易维护。IUrlHelper 接口是MVC与生成URL路由之间基础设施的基本块。可以通过控制器,视图以及视图组件中的URL属性找到一个可用的IUrlHelper实例:
public class HomeController : Controller { public IActionResult Index() { //生成/Home/Contact var url = Url.Action("Contact"); return View(); } public IActionResult Contact() { ViewData["Message"] = "Your application description page."; return View(); } }
这个URL路径是由路由值与当前请求相结合而成的路由创建,并将值传递给Url.Action,替换路由模板中对应的值。
上面Url.Action(的例子是常规路由,但是URL的生成工作与特性路由类似,尽管概念不同。在常规路由中,路由值被用来扩展模板,并且关于controller和action的路由值通常出现在那个模板,因为路由匹配的URL坚持了一个约定。在特性路由中,关于controller和action的路由值不允许出现在模板中--它们用来查找应该使用哪个模板,例如:
//修改Configure public void Configure(IApplicationBuilder app, IHostingEnvironment env) { app.UseMvc(); } public class HomeController : Controller { [HttpGet("https://www.jb51.net/")] public IActionResult Index() { //生成/Home/To/About var url = Url.Action("About"); return View(); } [HttpGet("Home/To/About")] public IActionResult About() { ViewData["Message"] = "Your application description page."; return View(); } }
MVC构建了一个所有特性路由操作的查找表,并且会匹配controller和action值来选择路由模板用于生成URL。
11.通过操作名生成URL
Url.Action(this IUrlHelper helper, string action) 以及所有相关的重载都是基于指定控制器名称和操作名来指定要链接的内容。