kims9
kims9

Reputation: 45

How to change area of mvc controller in .net mvc?

I have created new 'Admin' area, and i want to move there old two controllers with their views.(RoleManagerController, UserRolesController) I tried to cut and paste all the files and it didnt work. Then i tried deleting old files and creating new controllers by clicking on 'add new controller' and creating new views by rigth clicking on controller methods and selecting 'Create view', it didnt work as well.

Here is my project structure:

project structure

I have moved two controllers: RoleManagerController, UserRolesController from ~/Controllers to ~/Areas/Admin/Controllers. And their views from ~/Views to ~/Areas/Admin/Views.

When i try to access: localhost://Admin/RoleManager or localhost://Admin/UserRoles i get 404 HttpError: Admin/UserRolesAdmin/RoleManager

If i try to acces their old routes: 'localhost://UserRoles' and 'localhost://RoleManager' i get next errors: localhost://UserRoles localhost://UserRoles (routing)

It seems that even thought i have deleted and created a new controllers in the new area, routing got unchanged. here is my 'program.cs' file:

using HotelReservationSystem.Data;
using HotelReservationSystem.Models;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection");
builder.Services.AddDbContext<ApplicationDbContext>(options =>
    options.UseSqlServer(connectionString));
builder.Services.AddIdentity<ApplicationUser, IdentityRole>()
    .AddEntityFrameworkStores<ApplicationDbContext>()
    .AddDefaultUI()
    .AddDefaultTokenProviders();
builder.Services.AddDatabaseDeveloperPageExceptionFilter();

builder.Services.AddControllersWithViews();

var app = builder.Build();

// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseMigrationsEndPoint();
}
else
{
    app.UseExceptionHandler("/Home/Error");
    // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

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


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

});

//Seeding user Roles and Default admin user
using (var scope = app.Services.CreateScope())
{
    var services = scope.ServiceProvider;
    var loggerFactory = services.GetRequiredService<ILoggerFactory>();
    try
    {
        var context = services.GetRequiredService<ApplicationDbContext>();
        var userManager = services.GetRequiredService<UserManager<ApplicationUser>>();
        var roleManager = services.GetRequiredService<RoleManager<IdentityRole>>();
        await ContextSeed.SeedRolesAsync(userManager, roleManager);
        await ContextSeed.SeedSuperAdminAsync(userManager, roleManager);
    }
    catch (Exception ex)
    {
        var logger = loggerFactory.CreateLogger<Program>();
        logger.LogError(ex, "An error occurred seeding the DB.");
    }
}

app.Run();

/Areas/Admin/Controllers/RoleManagerController.cs

using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;

namespace HotelReservationSystem.Areas.Admin.Controllers
{
    public class RoleManagerController : Controller
    {
        private readonly RoleManager<IdentityRole> _roleManager;
        public RoleManagerController(RoleManager<IdentityRole> roleManager)
        {
            _roleManager = roleManager;
        }
        public async Task<IActionResult> Index()
        {
            var roles = await _roleManager.Roles.ToListAsync();
            return View(roles);
        }
        [HttpPost]
        public async Task<IActionResult> AddRole(string roleName)
        {
            if (roleName != null)
            {
                await _roleManager.CreateAsync(new IdentityRole(roleName.Trim()));
            }
            return RedirectToAction("Index");
        }
    }
}

/Areas/Admin/Views/RoleManager/index.cshtml:

    ViewData["Title"] = "Role Manager";
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h1>Менеджер ролей</h1>
<form method="post" asp-action="AddRole" asp-controller="RoleManager">
    <div class="input-group">
        <input name="roleName" class="form-control w-25">
        <span class="input-group-btn">
            <button class="btn btn-primary">Добавить новую роль</button>
        </span>
    </div>
</form>
<table class="table table-striped">
    <thead>
        <tr>
            <th>Id</th>
            <th>Роль</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var role in Model)
        {
            <tr>
                <td>@role.Id</td>
                <td>@role.Name</td>
            </tr>
        }
    </tbody>
</table>

Upvotes: 0

Views: 735

Answers (1)

Bhavikms
Bhavikms

Reputation: 61

You have to add Area attribute on top of your controller class to associate the controller with the area. E.g.

[Area("RoleManager")]
public class RoleManagerController : Controller
{
}

For more detail refer: https://learn.microsoft.com/en-us/aspnet/core/mvc/controllers/areas?view=aspnetcore-6.0

Upvotes: 1

Related Questions