【发布时间】:2019-04-25 18:17:01
【问题描述】:
更新(2)
@poke 似乎已经弄清楚了,如果与其他更高的路由存在歧义,那么它似乎是端点路由本身偏爱{*url} 的问题。
更新(1)
@poke 评论说我在{*url} 路由上有一个错字,其中 controller 中的 t 丢失了。在修复 {*url} 路由开始工作并且 DefaultController.Gone 操作开始工作后。
但是! 现在奇怪的行为又开始出现了。修复 {*url} 后,导航到应该与 {controller}/{action} 路由匹配的 /settings 失败并回退到 {*url} 路由。
如果我从注册中删除 {*url} 路由,那么 /settings 将再次起作用。 {action} 路由仍然不起作用。
原创
请原谅问题的篇幅,但我试图提供尽可能多的信息。
我正在为自己开发一个 ASP.NET Core 2.2 博客应用程序,但在路由正常工作时遇到了莫名其妙的问题。在对着屏幕大喊大叫半天之后,我决定退后一步,开始一个完全孤立的新项目。不知何故,问题在新项目中仍然存在。我已经把它剥离成一个饥饿的骨架,但我仍然无法让路线工作。我正在尝试设置的路线是:
settings/{controller}/{id:int}/{action} - works
settings/{controller}/{action} - works
blog/{*slug} - works
blog/{skip:int?} - works
{controller}/{action} - works
{action} - doesn't work
{*url} - doesn't work
具体来说,我在最后两条路线上遇到了问题。
{action} 路由不会为像 DefaultController.About 这样的简单操作生成,即使它没有约束,它所拥有的只是 PostsController.List 的默认值,因为我希望为根 URL 显示帖子列表。
{*url} 似乎根本不起作用。我想将它用作我的最终后备,它默认为DefaultController.Gone,但如果我只是在键盘上敲击一些无意义的 URL,我得到的只是 404 错误。
我觉得问题出在DefaultController 上,因为About 和Gone 动作都在其中,而且似乎都没有工作,但我似乎不知道怎么做。它实际上什么都不做,只是渲染视图,就像其他控制器一样。
下面是精简项目的代码。如果有人能启动它并告诉我哪里失败了,我将非常感激,因为我似乎无法弄清楚。
Program.cs
public sealed class Program {
public static async Task Main(
string[] args) => await WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.Build()
.RunAsync();
}
Startup.cs
public class Startup {
public void ConfigureServices(
IServiceCollection services) {
services.AddMvc()
.SetCompatibilityVersion(CompatibilityVersion.Latest);
}
public void Configure(
IApplicationBuilder app) {
app.UseMvc(
r => {
// /settings/{controller}/{id}/{action}
r.MapRoute("600", "settings/{controller}/{id:int}/{action}", null, new {
controller = "Categories|Tags"
});
// /settings/{controller}/{action}
r.MapRoute("500", "settings/{controller}/{action}", null, new {
controller = "Categories|Tags"
});
// /blog/*
r.MapRoute("400", "blog/{*slug}", new {
action = "Show",
controller = "Posts"
});
// /blog/{skip}
r.MapRoute("300", "blog/{skip:int?}", new {
action = "List",
controller = "Posts"
});
// /{controller}/{action}
r.MapRoute("200", "{controller}/{action=Default}", null, new {
controller = "Settings|Tools"
});
// /{action}
r.MapRoute("100", "{action}", new {
action = "List",
controller = "Posts"
});
// /*
r.MapRoute("-1", "{*url}", new {
action = "Gone",
conroller = "Default"
});
});
}
}
CategoriesController.cs
public sealed class CategoriesController :
Controller {
[HttpGet]
public IActionResult Add() => Content("Category added");
[HttpGet]
public IActionResult Remove(
int id) => Content($"Category {id} removed");
}
DefaultController.cs
public sealed class DefaultController :
Controller {
[HttpGet]
public IActionResult About() => View();
[HttpGet]
public IActionResult Gone() => View();
}
About.cshtml(默认)
<h1>DEFAULT.ABOUT</h1>
Gone.cshtml(默认)
<h1>DEFAULT.GONE</h1>
PostsController.cs
public sealed class PostsController :
Controller {
[HttpGet]
public IActionResult List(
int? skip) => View();
[HttpGet]
public IActionResult Show(
string slug) => View();
}
List.cshtml(帖子)
<h1>POSTS.LIST</h1>
<a asp-action="Show" asp-controller="Posts" asp-route-slug="test-test-test">Show a Post</a>
Show.cshtml(帖子)
<h1>POSTS.SHOW</h1>
SettingsController.cs
public sealed class SettingsController :
Controller {
[HttpGet]
public IActionResult Default() => View();
}
Default.cshtml(设置)
<h1>SETTINGS.DEFAULT</h1>
<a asp-action="Add" asp-controller="Categories">Add a Category</a>
<br />
<a asp-action="Remove" asp-controller="Categories" asp-route-id="1">Remove a Category</a>
<hr />
<a asp-action="Add" asp-controller="Tags">Add a Tag</a>
<br />
<a asp-action="Remove" asp-controller="Tags" asp-route-id="1">Remove a Tag</a>
TagsController.cs
public sealed class TagsController :
Controller {
[HttpGet]
public IActionResult Add() => Content("Tag added");
[HttpGet]
public IActionResult Remove(
int id) => Content($"Tag {id} removed");
}
ToolsController.cs
public sealed class ToolsController :
Controller {
[HttpGet]
public IActionResult Default() => View();
}
Default.cshtml
<h1>TOOLS.DEFAULT</h1>
_Layout.cshtml
<!DOCTYPE html>
<html>
<head>
<title>@ViewBag.Title</title>
</head>
<body>
<a asp-action="List" asp-controller="Posts">Blog</a>
<br />
<a asp-action="Default" asp-controller="Tools">Tools</a>
<br />
<a asp-action="About" asp-controller="Default">About</a>
<br />
<a asp-action="Default" asp-controller="Settings">Settings</a>
<br />
@RenderBody()
</body>
</html>
【问题讨论】:
-
conroller = "Default"- 有一个错字,t不见了。这能解决吗? ?????? -
@poke,谢谢,它修复了
{*url}路由,但{action}路由仍然没有生成。奇怪的/settings应该匹配{controller}/{action}路由现在失败并回退到{*url}路由。如果我从注册中删除{*url}路由,那么/settings将再次起作用。我开始回想起原始项目中奇怪的行为。 :(
标签: c# asp.net-core routing asp.net-core-2.2