c# - 与包含可能位于中间的模式的任何 URL 匹配的 ASP.NET Core MVC 路由
问题描述
通常,MVC 路由是通过从 URL 的开头匹配模式来完成的,例如:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(name: "MyRoute", pattern: "my.io/{*suffix}", defaults: new { controller = "MyController" });
});
但是,如果我想定义一个路由来捕获包含特定模式的任何请求,而不管它在 URL 路径中的哪个位置可以找到呢?像这样的东西:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(name: "MyRoute", pattern: "{*prefix}/my.io/{*suffix}", defaults: new { controller = "MyController" });
});
正如您所希望看到的,我想捕获碰巧包含模式“/my.io/”的任何请求,无论它是否在 URL 的开头(通常是这样),在 URL 的中间,或在 URL 的末尾。在所有情况下,我还想捕获前缀和后缀,如果有的话。不用说,这些可能会发生不可预测的变化,这是我想使用通配符执行此操作的重要部分原因。
有没有办法使用 MVC 端点路由来做到这一点?
如果是,那么必须如何编写[Route()]
属性MyController
及其方法才能被路由子系统发现?
如果没有,我的替代方案是什么?
更新
经过一番研究,我确定我的问题与此类似。不幸的是,那里没有明确的答案......
解决方案
经过一些试验,我发现也许@panagiotis-kanavos 为我指明了正确的方向,毕竟!
虽然前缀和后缀确实可以大不相同(内容和长度),但我意识到长度仍然存在一些最终限制。
然后我定义了一些这样的路线:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(name: "Api0", pattern: "my.io", defaults: new { controller = "MyController" });
endpoints.MapControllerRoute(name: "Api1", pattern: "{part1}/my.io", defaults: new { controller = "MyController" });
endpoints.MapControllerRoute(name: "Api2", pattern: "{part1}/{part2}/my.io", defaults: new { controller = "MyController" });
endpoints.MapControllerRoute(name: "Api3", pattern: "{part1}/{part2}/{part3}/my.io", defaults: new { controller = "MyController" });
endpoints.MapControllerRoute(name: "Api4", pattern: "{part1}/{part2}/{part3}/{part4}/my.io", defaults: new { controller = "MyController" });
endpoints.MapControllerRoute(name: "Api5", pattern: "{part1}/{part2}/{part3}/{part4}/{part5}/my.io", defaults: new { controller = "MyController" });
// ... and a couple more along the same vein.
});
接下来,我[Route]
在 MyController 上定义了多个匹配的属性:
[Route("my.io")]
[Route("{part1}/my.io")]
[Route("{part1}/{part2}/my.io")]
[Route("{part1}/{part2}/{part3}/my.io")]
[Route("{part1}/{part2}/{part3}/{part4}/my.io")]
[Route("{part1}/{part2}/{part3}/{part4}/{part5}/my.io")]
...
my.io
这成功地处理了包含最多 5 级前缀的任何 URL 。当然,这可以实际扩展到我需要的极限。 请参阅下面的重要编辑!
一旦我点击了我的操作方法,我就可以像这样简单地一次性读取整个后缀:
[Route("{*suffix}")]
在该方法中我需要做的唯一工作是将所有{partN}
片段拼接在一起,我也可以直接从Request.Url
.
重要编辑
看来我说话有点太早了。幸运的是,上述解决方案最多可用于 5 个段前缀。我确实注意到内存使用量略有增加,但除此之外一切正常。
但是一旦我添加了一个 6 段前缀,应用程序启动就开始明显滞后,并且内存使用量比以前翻了一番。
添加 7 段前缀会导致我的应用程序在启动时消耗超过 4 GB 的内存(通常应该低于 300 MB)并且服务请求变得非常慢。
似乎有一些指数级的恶作剧正在上演。不幸的是,这意味着这个解决方案比我最初认为的要有限得多。
重要编辑 2
经过进一步的实验,我确定不是endpoints.MapControllerRoute()
调用缓慢和消耗内存的原因,而是[Route]
控制器上的属性。当这些值超过 5 时,事情很快就会停止。我想知道这是为什么?
我怎样才能让它变得更好?
重要编辑 3
我在这个问题中向 ASP.NET Core 团队提出了这个问题。我们会看到它的去向。
推荐阅读
- python - 如何在 Python 中计算冒泡排序中的交换次数
- python - Julia:龙格库塔法的计算时间
- python - 在 python 中显示 SyntaxError
- ios - 当两个用户之间正在进行来电并收到另一个来电时,应自动拒绝另一个来电
- ansible - 为什么 Ansible 变量覆盖策略的行为似乎不像记录的那样?
- java -
实现 'com.chaos.view:pinview:1.4.4' 当我尝试在我的布局上调用它时它什么也不显示
<com.chaos.view.PinView android:layout_width="wrap_content"
- c# - 如何更改所选行中列的可见性?
- python - 如何从给定列表中创建具有特定标题的数据框列表
- excel - 如何在 For Next 中应用 Step -1 以相反的顺序循环?
- python - TypeError: 'numpy.int64' object is not iterable - 所有值都是浮点数,但我仍然收到错误消息。我该如何解决这个问题?