Search code examples
asp.net-mvcasp.net-corerazorasp.net-mvc-areas

In my MVC .NET Core 3.1 project, how can I prevent the anchor tag helper from appending Area to the querystring?


I'm migrating an old MVC web application from Visual Studio to Visual Studio Code, and am using .NET Core 3.1.301. The application uses areas. I'm attempting to create a link from this site's home page to the index page of a target area.

Using the anchor tag helper, my Razor resembles this:

<a asp-area="TargetArea" asp-controller="Home" asp-action="Index">link</a>

My expectation is that the above will produce this markup in the rendered HTML:

<a href="/TargetArea">link</a>

Instead, this gets rendered:

<a href="/TargetArea?area=TargetArea">link</a>

In Startup.cs I have defined TargetArea:

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

In the HomeController within my area, I've decorated the controller with an Area attribute, like so:

[Area("TargetArea")]
public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }
}

So what am I missing here? I'd like to make that query-string go away. Thanks for your help.


Solution

  • Change your route template like below:

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

    The second way:

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

    Another way:

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

    Reference:

    https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-3.1#areas