首页 > 解决方案 > Asp.Net Core 端点路由

问题描述

我有Action一个Controller

[Route("")]
[Route("{pageNumber?}")]
[Route("tag/{tagSlug?}/{pageNumber?}")]
public async Task<IActionResult> Index(int? pageNumber, string tagSlug = null, string searchTerm = null)
{
    var model = await repoPm_.GetPage(pageNumber, tagSlug, searchTerm);
    return View(model);
}

每个项目都有一个与之关联的标签列表

@foreach (var t in item.Tags)
{
    <a asp-action="Index" asp-route-tagSlug="@t.TagSlug" class="mr-3">@t.Name</a>
}

在我的导航栏中,我有一个指向该页面的链接,我尝试了以下操作:

<a asp-area="" asp-controller="Items" asp-action="Index" asp-route-tagSlug="">Items</a>
<a asp-area="" asp-controller="Items" asp-action="Index" asp-route-tagSlug="@null">Items</a>
<a asp-area="" asp-controller="Items" asp-action="Index">Items</a>

当我不在该页面上时,导航栏中的链接指向/items/tag哪个很烦人,但它可以工作。

当我在该页面上并单击其中一个标签时,Omnibar 中的 URL 是正确的,即/items/tag/fancy-items

问题是这也是为我的导航栏中的链接生成的 url,即/items/tag/fancy-items它应该是什么时候/items

我究竟做错了什么?我不想进入一堆路由映射Startup.cs,似乎<a asp-area="" asp-controller="Items" asp-action="Index">Items</a>应该可以工作

标签: c#asp.net-coreasp.net-core-routing

解决方案


您可以使用重载来分隔不同的路由,以使它们的 URL 彼此离散。

这样,调用Index不带参数的操作只能通过/items访问,并且 ASP.NET 的运行时绑定行为不会错误地解析为不同的 URL。

我的建议是使顶级 Action 调用重载,以解决相同的底层方法以实现可重用性。

[Route("")]
public async Task<IActionResult> Index()
{
    return await WrappedMethod(null);
}


[Route("tag/{pageNumber}")]
public async Task<IActionResult> Index(int pageNumber)
{
    return await WrappedMethod(pageNumber);
}

[Route("tag/{tagSlug}/{pageNumber}")]
public async Task<IActionResult> Index(string tagSlug, int? pageNumber)
{
    return await WrappedMethod(pageNumber, tagSlug);
}

private async Task<IActionResult> WrappedMethod(int? pageNumber, string tagSlug = null, string searchTerm = null)
{
    var model = await repoPm_.GetPage(pageNumber, tagSlug, searchTerm);
    return View(model);
}

请注意,参数本身的可空性将取决于您的用例。


推荐阅读