asp.net mvc Anchor Tag Helpers 生成 html "id" 是查询字符串的一部分,不是路由数据的一部分

asp.net mvc Anchor Tag Helpers generates html "id" is part of the query string ,not part of the route data

Startup.cs

public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
    if (env.IsDevelopment()) {
        app.UseDeveloperExceptionPage();
     } else {
        app.UseExceptionHandler("/Home/Error");
     }
     app.UseStaticFiles();

     app.UseRouting();

     app.UseAuthentication();
     app.UseAuthorization();

     app.UseCookiePolicy(new CookiePolicyOptions {
         MinimumSameSitePolicy = SameSiteMode.Strict,
     });

     app.UseEndpoints(endpoints => {
         endpoints.MapControllerRoute(
              name: "default",
              pattern: "{controller=Home}/{action=Index}/{id?}");
     });
}

CustomerController.cs

URL: /customer/details/7

[Authorize(Roles = "Admin")]
public async Task<IActionResult> Details(int id) {
    var model = GetUser();
    return View(model);
}

添加以下代码后 (获取当前登录客户的详细信息)

URL: /customer/details

[Route("[controller]/[action]")]
public async Task<IActionResult> Details() {
    int userId = Convert.ToInt32(HttpContext.User.Identity.Name);
    return await Details(userId);
}

锚标记助手生成 html“id”是查询字符串的一部分,而不是路由数据的一部分。

<a  asp-action="Details" asp-controller="Customer" asp-route-id="@HttpContextAccessor.HttpContext.User.Identity.Name">User Details</a>

它生成这个 HTML:

<a  href="/Customer/Details?id=1">User Details</a>

如何仍然生成HTML :

<a  href="/Customer/Details/1">User Details</a>

谢谢

要点 1:您的默认路由模板是

     app.UseEndpoints(endpoints => {
         endpoints.MapControllerRoute(
              name: "default",
              pattern: "{controller=Home}/{action=Index}/{id?}");
     });

要点 2:如果您将路由直接添加到您的控制器操作,这将覆盖默认路由,因为您的两个操作具有相同的名称,您还需要将路由添加到另一个操作。检查下面的代码,这是。

解决方案 1

[Authorize(Roles = "Admin")]
[Route("[controller]/[action]/{id}")]
public async Task<IActionResult> Details(int id) {
    var model = GetUser();
    return View(model);
}

[Route("[controller]/[action]")]
public async Task<IActionResult> Details() {
    int userId = Convert.ToInt32(HttpContext.User.Identity.Name);
    return await Details(userId);
}

要点3:如果您可以更改其他控制器的动作名称,那么您可以使用这种方法。直接重命名没有路由的动作即可。

解决方案 2

[Authorize(Roles = "Admin")]
public async Task<IActionResult> Details2(int id) {
    var model = GetUser();
    return View(model);
}

[Route("[controller]/[action]")]
public async Task<IActionResult> Details() {
    int userId = Convert.ToInt32(HttpContext.User.Identity.Name);
    return await Details(userId);
}