Routing between ASP.NET Core web application and Razor Class Library projects

Viewed 1089

I created a project ASP.NET Core 3.0 MVC and it works fine. In the same solution, I added 3 (or more) projects "Razor Class Library". Each such project has a controller. How do I configure routing so that I can access the controller methods of these projects?

My solution looks like this:

MyProject.Shop (Razor Class Library)
|_ Controllers
    |_ HomeController.cs
MyProject.Books (Razor Class Library)
|_ Controllers
    |_ HomeController.cs
MyProject.Web (main ASP.NET Core 3.0 MVC project)
|_ Controllers
    |_ HomeControlles.cs

Currently, routing works perfectly only within one main project. You can't access the controller in Myproject.Book etc. Maybe you need to configure Application Parts, but how do I do this in my case?

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

There are a few things you need to do in order to make this work for each library, so let's go over each one, using your Shop library as an example, and this is for ASP.NET Core 3.1.

Add a reference to your Razor class library from your Web project

Right-click the Dependencies folder of your Web project, select Add Project Reference..., check the box next to Shop and click OK.

Make sure your controllers and views folders are under an Areas/AreaName/ folder

In your case, this means your controllers and views should be under an Areas/Shop folder, like this:

Razor class library folder structure

Decorate the controllers in your library with an AreaAttribute

For your Shop project, this means doing the following for your Shop project's HomeController class:

[Area("shop")]
public class HomeController : Controller

Copy _ViewStart.cshtml to your Shop project

From your Web project, copy Views/_ViewStart.cshtml to your Shop project's Areas/Shop/Views folder. It should look like this:

shop-view-start-folder-placement

This is so your layout is consistent between your Web and Shop projects.

Update your routing configuration in your Web project to include routing for the area

In this example, the routes are configured in your Web project's Startup.cs like so:

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

Now, launching your application and going to the default URL should show you the normal home page, but navigating to /shop will show you whatever you have in your Views/Shop/Index.cshtml view.

From doing the above, I see the home page:

home-page

and can also navigate to the shop:

shop-page

...and I'm apparently hungry and wanting icecream.

Naturally, you'll need to go through the same kind of process for your Books library.

The structure of the whole solution is below:

enter image description here

Razor Class Library

Configuration

<Project Sdk="Microsoft.NET.Sdk.Razor">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <RazorLangVersion>3.0</RazorLangVersion>
  </PropertyGroup>


  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components" Version="3.1.6" />
    <PackageReference Include="Microsoft.AspNetCore.Components.Web" Version="3.1.6" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.ViewFeatures" Version="2.2.0" />
  </ItemGroup>

</Project>

Codes of Controller

using Microsoft.AspNetCore.Mvc;

namespace MyProject.Controllers
{
    [Area("books")]
    public class HomeController : Controller
    {
        public string Index()
        {
            return "Books Home Index";
        }
    }
}

Main MVC project

Codes of Startup.cs in ASP.NET Core 3.0 MVC project

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

Add Project Reference...

enter image description here

Test

enter image description here

Related