No webpage was found for the web address: https://localhost:7002/Category/Add?area=Admin. Why is my URL generated like ?area=Admin instead of /Admin/

60 views Asked by At

I have an Admin area in my ASP.NET Core MVC app and when I try to reach to /Admin/Category/Add it says No webpage was found for the web address: https://localhost:7002/Category/Add?area=Admin.

My routing in program.cs:

app.MapDefaultControllerRoute();

app.MapAreaControllerRoute(
        name: "Admin",
        areaName: "Admin",
        pattern: "Admin/{controller=Home}/{action=Index}/{id?}"
        );

My view:

@model List<Category>

@{
    ViewData["Title"] = "Index";
    Layout = "~/Areas/Admin/Views/Shared/_AdminLayout.cshtml";
}

<div class="row">
    <div class="col-lg-12">
        <div class="card">
            <div class="card-body">

                <a asp-area="Admin" asp-controller="Category" asp-action="Update" class="btn mb-1 btn-primary">Add Category</a>

                <div class="card-title">
                    <h4>Table Basic</h4>
                </div>
                <div class="table-responsive">
                    <table class="table">
                        <thead>
                            <tr>
                                <th>Name</th>
                                <th>Created By</th>
                                <th>Status</th>
                                <th>Actions</th>
                            </tr>
                        </thead>
                        <tbody>
                            @foreach (var item in Model)
                            {
                                <tr>
                                    <td>@item.Name</td>
                                    <td>@item.CreatedBy</td>
                                    <td>@item.IsDeleted</td>
                                    <td>
                                        <a asp-area="Admin" asp-controller="Category" asp-action="Update" asp-route-id="@item.Id">
                                            <button type="button" class="btn mb-1 btn-warning">Update</button>
                                        </a>
                                        <a asp-area="Admin" asp-controller="Category" asp-action="Delete" asp-route-id="@item.Id">
                                            <button type="button" class="btn mb-1 btn-danger">Delete</button>
                                        </a>
                                    </td>
                                </tr>
                            }
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>

My controller:

namespace AnimeUI.Areas.Admin.Controllers
{
    [Area("Admin")]
    public class CategoryController : Controller
    {
        private readonly ICategoryService categoryService;
        private readonly IValidator<Category> validator;
        private readonly IMapper mapper;

        public CategoryController(ICategoryService categoryService, IValidator<Category> validator, IMapper mapper)
        {
            this.categoryService = categoryService;
            this.validator = validator;
            this.mapper = mapper;
        }

        public async Task<IActionResult> Index()
        {
            var categories = await categoryService.GetAllCategoriesNonDeletedAsync();

            return View(categories);
        }

        [HttpGet]
        public IActionResult Add()
        {
            return View();
        }

        [HttpPost]
        public async Task<IActionResult> Add(AddCategoryDto addCategoryDto)
        {
            var category = mapper.Map<Category>(addCategoryDto);
            var result = validator.Validate(category);
            var exists = await categoryService.Exists(category);

            if (exists)
                result.Errors.Add(new ValidationFailure("Name", "This category name already exists"));

            if (result.IsValid)
            {
                await categoryService.CreateCategoryAsync(addCategoryDto);
                return RedirectToAction("Index", "Category", new { Area = "Admin" });
            }

            result.AddToModelState(this.ModelState);

            return View(addCategoryDto);
        }
    }
}

I have been searching for whole day, yet couldn't find a valid solve to this annoying problem. For some reason my URL is being generated like this:

https://localhost:7002/Category/Add?area=Admin

instead of

https://localhost:7002/Admin/Category/Add

I tried to change my port, add different routing syntax. I am currently using Visual Studio 2022 and my project is .NET 8.0

PS: My problem only occurs when I need to go to the pages of Admin.

1

There are 1 answers

2
Jackdaw On BEST ANSWER

I suggest to follow the steps described in the official documentation when creating/using areas: Areas in ASP.NET Core

When following the documentation and adding an area you see the following ScaffoldingReadMe.txt:

Scaffolding has generated all the files and added the required dependencies.

However the Application's Startup code may require additional changes for things to work end to end.
Add the following code to the Configure method in your Application's Startup class if not already done:

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

This is exactly what intended to make the routing process work correctly. In your case use the following code:

app.UseRouting();

app.UseAuthorization();

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

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

app.Run();

The pattern areas described above is generic and will be used for another areas too.

Don't forget to use correct Area folder structure too.


By the way, you code is working good for me. Therefore, I suppose your problem is caused by incorrect folders structure: use Add > Area... menu command from the Area folder. The Visual Studio template will help you to avoid mistakes.