Search code examples
c#asp.net-mvcasp.net-coreroutes

How do l solve directory issues on my ASP.NET MVC project? Each time l am taken to the Identity folder, the folder locations of my views are changed?


I'm experiencing a routing issue where navigating to certain pages, such as the Admin Index, results in a "page not found" error because the views are not located inside the Areas folder, and the routing configuration doesn't correctly point to the appropriate view directories.

I've tried configuring the routes in my Program.cs as follows:

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

// Admin routes
app.MapControllerRoute(
    name: "admin",
    pattern: "{controller=Admin}/{action=Index}/{id?}");

However, I'm still facing issues when trying to access the admin pages or home pages while being located in the Identity folder.

Here's the relevant portion of my layout page:

<header>
    <h3>Online Mart</h3>

    @if (SignInManager.IsSignedIn(User))
    {
        if (User.IsInRole("admin"))
        {
            <nav class="nav-bar">
                <a asp-controller="Admin" asp-action="Index">Dashboard</a>
                <a asp-controller="Product" asp-action="Index">Products</a>
                <a asp-controller="Category" asp-action="Index">Categories</a>
                <a asp-controller="Orders" asp-action="Index">Orders</a>
                <a asp-controller="Customers" asp-action="Index">Customers</a>
            </nav>
        }
        else
        {
            <nav class="nav-bar">
                <a asp-controller="Home" asp-action="Index">Home</a>
                <a asp-controller="Shop" asp-action="Index">Shop</a>
                <a asp-controller="Cart" asp-action="Index">Cart</a>
                <a asp-controller="Orders" asp-action="Index">Orders</a>
                <a asp-controller="Home" asp-action="Aboutus">About</a>
            </nav>
        }
    }
    else
    {
        <nav class="nav-bar">
            <a asp-area="" asp-controller="Home" asp-action="Index">Home</a>
            <a asp-controller="Shop" asp-action="Index">Shop</a>
            <a asp-controller="Cart" asp-action="Index">Cart</a>
            <a asp-controller="Orders" asp-action="Index">Orders</a>
            <a asp-controller="Home" asp-action="Aboutus">About</a>
        </nav>
    }

    <partial name="_LoginPartial" />
</header>

LoginPartial view:

@inject SignInManager<AppUser> SignInManager
@inject UserManager<AppUser> UserManager

<ul class="navbar-nav">
    @if (SignInManager.IsSignedIn(User))
    {
        if (User.IsInRole("admin"))
        {
            <li class="nav-item dropdown nav-bar">
                <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="true">Admin</a>

                <ul class="dropdown-menu">
                    <li>
                        <a class="dropdown-item text-dark" asp-area="Identity" asp-controller="Account" asp-action="Manage">Profile</a>
                    </li>
                    <li><hr class="dropdown-divider" /></li>
                    <li>
                        <a class="dropdown-item text-dark" asp-area="Identity" asp-controller="Account" asp-action="Logout">Logout</a>
                    </li>
                </ul>
            </li>
        }
        else
        {
            <li class="nav-item dropdown nav-bar">
                <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="true">User</a>

                <ul class="dropdown-menu">
                    <li>
                        <a class="dropdown-item text-dark" asp-area="Identity" asp-controller="Account" asp-action="Manage">Profile</a>
                    </li>
                    <li><hr class="dropdown-divider" /></li>
                    <li>
                        <a class="dropdown-item text-dark" asp-area="Identity" asp-controller="Account" asp-action="Logout">Logout</a>
                    </li>
                </ul>
            </li>
        }
    }
    else
    {
        <div class="nav-bar">
            <a id="register" asp-area="Identity" asp-controller="Account" asp-action="Register">Register</a>
            <a id="login" asp-area="Identity" asp-controller="Account" asp-action="Login">Login</a>
        </div>
    }
</ul>

Solution

  • Firstly, if you are using the built-in scaffold identity pages. They are "Razor pages", not "MVC". They just need to be route using

    app.MapRazorPages();
    

    and navlink would be like

    <div class="nav-bar">
        <a class="nav-link" asp-area="Identity" asp-page="/Account/Register">Register</a>
        <a class="nav-link" asp-area="Identity" asp-page="/Account/Login">Login</a>
    </div>
    

    Secondly, according to your codes, you should have an area named "admin". You need make sure the controller has area attribute

        [Area("admin")]
        public class AdminController : Controller
        {
    

    and add route like below.

    app.MapControllerRoute(
            name: "areas",
            pattern: "{area:exists}/{controller=Home}/{action=Index}/{id?}"
        );
    

    It is a routing template and works for following area folder structure.
    enter image description here
    Then you could visit by /admin/admin/index

    If you want to point to the view which is in other location. You could use like

        public IActionResult Index()
        {
            return View("~/{folderPath}/Index.cshtml");
        }
    

    and navlink would be like

    <a asp-area="admin" asp-controller="Admin" asp-action="Index">Admin Home</a>