Asp.Net核心端点路由

时间:2019-10-25 16:09:19

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

我在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

问题在于,这也是我的导航栏中链接的生成网址,即/items/tag/fancy-items,当它应该只是/items

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

1 个答案:

答案 0 :(得分:1)

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

这样,Index只能访问没有参数的/items动作,并且ASP.NET的运行时绑定行为不会错误地解析为另一个URL。 / p>

我的建议是使顶级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);
}

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