ASPNET Core 30中使用动态控制器路由

原文:Dynamic controller routing in ASP.NET Core 3.0[1]

作者:Filip W[2]

译文:https://www.cnblogs.com/lwqlun/p/11461657.html

译者:Lamond Lu

译者注

今天在网上看到了这篇关于ASP.NET Core动态路由的文章,感觉蛮有意思的,给大家翻译一下,虽然文中的例子不一定会在日常编码中出现,但是也给我们提供了一定的思路。

前言

相对于ASP.NET MVC以及ASP.NET Core MVC中的旧版本路由特性, 在ASP.NET Core 3.0中新增了一个不错的扩展点,即程序获取到路由后,可以将其动态指向一个给定的controller/action.

这个功能有非常多的使用场景。如果你正在使用从ASP.NET Core 3.0 Preview 7及更高版本,你就可以在ASP.NET Core 3.0中使用它了。

PS: 官方没有在Release Notes中提到这一点。

下面就让我们一起来看一看ASP.NET Core 3.0中的动态路由。

背景

当我们使用MVC路由的时候,最典型的用法是,我们使用路由特性(Route Attributes)来定义路由信息。使用这种方法,我们需要要为每个路由进行显式的声明。

相对的,你可以使用中心化的路由模型,使用这种方式,你就不需要显式的声明每一个路由 - 这些路由会自动被所有发现的控制器的自动识别。然而,这样做的前提是,所有的控制器首先必须存在。

以下是ASP.NET Core 3.0中使用新语法Endpoint Routing的实现方式。

以上两种方式的共同点是,所有的路由信息都必须在应用程序启动时加载。

但是,如果你希望能够动态定义路由, 并在应用程序运行时添加/删除它们,该怎么办?

下面我给大家列举几个动态定义路由的使用场景。

•多语言路由,以及使用新语言时,针对那些新语言路由的修改。•在CMS类型的系统中,我们可能会动态添加一些新页面,这些新页面不需要创建的控制器或者在源码中硬编码路由信息。•多租户应用中,租户路由可以在运行时动态激活或者取消激活。

这个问题的处理过程应该相当的好理解。我们希望尽早的拦截路由处理,检查已为其解析的当前路由值,并使用例如数据库中的数据将它们“转换”为一组新的路由值,这些新的路由值指向了一个实际存在的控制器。

实例问题 - 多语言翻译路由问题

在旧版本的ASP.NET Core MVC中, 我们通常通过自定义接口,来解决这个问题。然而在ASP.NET Core 3.0中这种方式已经行不通了,因为路由已经改由上面提到的Endpoint Routing来处理。值得庆幸的是,ASP.NET Core 3.0 Preview 7以及后续版本中,我们可以通过一个新特性以及一个扩展点, 来支持我们的需求。下面让我们看一个具体的例子。

想象一下,在你的项目中,有一个控制器,然后你希望它支持多语言翻译路由。

我们可能希望的请求的URL是这样的,例如

•英语 -/en/orders/list•德语 -/de/bestellungen/liste•波兰语 -/pl/zamowienia/lista使用动态路由处理多语言翻译路由问题

那么我们现在该如何解决这个问题呢?我们可以使用新特性来替代默认的MVC路由, 并将其指向我们自定义的类, 该类实现了我们之前提到的路由值转换 。

这里我们定义了一个类,它继承了类。这个新类将负责将特定语言路由值,转换为可以在我们应用可以匹配到controller/action的路由值字典,而这些值通常不能直接和我们应用中的任何controller/action匹配。所以这里简单点说,就是在德语场景下,controller名会从“Bestellungen”转换成"Orders", action名"Liste"转换成"List"。

类被作为泛型类型参数,传入方法中,它必须在依赖注入容器中注册。这里,我们还需要注册一个类,但是这个类仅仅为了帮助演示,后面我们会需要它。

在这个转换器中,我们需要尝试提取3个路由参数,,,,然后我们需要在模拟用的数据库类中,找到其对应的翻译。正如我们之前提到的,你通常会希望从数据库中查找对应的内容,因为使用这种方式,我们可以在应用程序生命周期的任何时刻,动态的影响路由。为了说明这一点,我们将使用类来模拟数据库操作,这里你可以把它想象成一个真正的数据库仓储服务。

到目前为止,我们已经很好的解决了这个问题。这里通过在MVC应用中启用这个设置,我们就可以向我们之前定义的3个路由发送请求了。

•英语 -/en/orders/list•德语 -/de/bestellungen/liste•波兰语 -/pl/zamowienia/lista

每个请求都会命中控制器和方法。当前你可以将这个方法进一步扩展到其他的控制器。但最重要的是,如果新增一种新语言或者新的路由别名映射到现有语言中的controller/actions,你是不需要做任何代码更改,甚至重启项目的。

请注意,在本文中,我们只关注路由转换,这里仅仅是为了演示ASP.NET Core 3.0中的动态路由特性。如果你希望在应用程序中实现本地化,你可能还需要阅读ASP.NET Core 3.0的本地化指南[3], 因为你可以需要根据语言的路由值设置正确的。

最后, 我还想再补充一点,在我们之前的例子中,我们在路由模板中显式的使用了和占位符。这并不是必须的,在其他场景中,你还可以使用路由通配符,并将其转换为controller/action路由值。

路由通配符是CMS系统中的典型解决方案,你可以使用它来处理不同的动态“页面”路由。

它看起来可能类似:

然后,你需要将之后的整个URL参数转换为现有可执行控制器的内容 - 通常URL/路由的映射是保存在数据库中的。

希望你会发现这篇文章很有用 - 所有的演示源代码都可以在Github[4]上找到。

References

Dynamic controller routing in ASP.NET Core 3.0:https://www.strathweb.com/2019/08/dynamic-controller-routing-in-asp-net-core-3-0/

Filip W:http://twitter.com/filip_woj

本地化指南:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization?view=aspnetcore-3.0

Github:https://github.com/filipw/Strathweb.Samples.DynamicControllerRouting

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190905A09LQF00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券