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

200 Views Asked by At

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);
}

After adding the following code (get the detailed information of the currently logged in customer)

URL: /customer/details

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

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

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

It generates this HTML:

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

How to still generates HTML :

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

Thanks

1

There are 1 best solutions below

0
tontonsevilla On BEST ANSWER

Point 1: Your default routing template is

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

Point 2: If you put a routing directly to your controller action this will override the default routing since your two action has the same name, you need to also add a routing to the other one. Check the below code, this is.

SOLUTION 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);
}

Point 3: If you can change the action name of the other controller then you can go with this approach. Just rename the action which has no routing directly on it.

SOLUTION 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);
}