Instructor-led online courses in ASP.NET Core, ASP.NET MVC, and ASP.NET Design Patterns. Read more...
Live instructor-led online courses in ASP.NET Core and Design Patterns. Registration is open for December 2018 batch. More details are available here.

Reuse UI with Razor Class Libraries (RCL) in ASP.NET Core

Developers always look for ways to reuse their code and markup. ASP.NET Core offers several ways to reuse code and markup within a project (partials, custom tag helpers, view components etc.). What if you want to reuse a piece of user interface (UI) across multiple web applications? Luckily, ASP.NET Core 2.1 introduced what is known as Razor Class Library (RCL) projects that can be used to accomplish this task.

Simply put, RCL is a collection of view models, controllers, views, layouts, and partials that you want to reuse across multiple applications. RCL also allows you to isolate pieces of UI from your web application. Of course, you don't need to put all these pieces into RCL. For example, you may want to isolate only views and partials into RCL and not the controllers. It's up to you as a developer to decide what and how you would like to reuse the UI.

In order to create a new RCL, Visual Studio provides a project template as shown below :

As you can see, the ASP.NET Core 2.1 includes Razor Class Library project template. The resultant project is similar to a normal class library but uses Razor SDK. The default RCL project assumes that you are going to use ASP.NET Core Areas to organize your applications. By default it is also assumed that you are using Razor Pages. However, you are not bound by these defaults. In the example that follows we will be using ASP.NET Core MVC organized into typical folder structure (we won't use areas).

The following figure shows how our view models, views, and controllers can be organized.

As you can see we have created the typical MVC folder structure inside the RCL project. Let's summarize this file organization for the sake of clarity :

  • Controllers folder contains one or more controllers that you want to reuse. In this case we want to reuse HomeController.
  • The ViewModels folder contains view models (you can call it just Models if you so wish) and contains Employee view model class.
  • The Views folder contains _ViewImports and _ViewStart files.
  • The Views > Home folder contains Index view.
  • The Views > Shared folder contains layouts and partials shared by the views.

Ok. Begin by creating a new RCL and also add the ViewModels, Views, and Controllers folders.

The Employee view model class is shown below:

public class Employee
{
    public int EmployeeID { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

Then add _Layout.cshtml to the Views folder and write the following markup in it :

<!DOCTYPE html>

<html>
<head>
    <meta name="viewport" content="width=device-width" />
    <title>@ViewBag.Title</title>
</head>
<body>
    <h1>Welcome to RCL!</h1>
    <hr />
    <div>
        @RenderBody()
    </div>
</body>
</html>

Then add _Partials.cshtml file and modify it a shown below :

<h2>@ViewBag.Message</h2>

It simply outputs Message ViewBag property. The Message property is set by the HomeController.

Then add _ViewStart.cshtml and _ViewImports.cshtml files as shown below :

@{
    Layout = "_Layout";
}

And

@using RCL.ViewModels;
@addTagHelper *,Microsoft.AspNetCore.Mvc.TagHelpers

Now add Index.cshtml and modify it as shown below :

@model Employee

<h1>RCL - @ViewBag.Title</h1>

<h3>
    @Html.DisplayForModel()
</h3>

<hr />

<partial name="_Partial" />

As you can see, we simply output the Employee model data using the DisplayForModel() method. We also render the _Partial using the <partial> tag helper.

Finally, add HomeController and write its Index() action as follows :

public IActionResult Index()
{
    Employee emp = new Employee()
    {
        EmployeeID = 1,
        FirstName = "Nancy",
        LastName = "Davolio"
    };

    ViewBag.Title = "Employee Details";

    ViewBag.Message = $"Last updated on 
{DateTime.Now.ToShortDateString()}";

    return View(emp);
}

The Index() action prepares an Employee model object. It also sets Title and Message ViewBag properties.

This completes the RCL code.

Next, add an ASP.NET Core web application project to the same solution.

Then add a reference to the RCL library you just created using the Add Reference dialog :

After adding the project reference of the RCL project the web application looks like this :

The web application doesn't have any view model, controller, or views. Press F5 to run the application. If all goes well your browser should resemble this :

As you can see, the view model, views, partial, layout - all has been correctly picked from the RCL.

Overriding the views

If you wish you can also override the views, partials, and layouts provided by the RCL by adding them in the web application. Consider the following :

Here, we added Views folder to the web application. The Views folder has its own Index.cshtml, _Layout.cshtml, and _Partial.cshtml. Since the web application has its own razor code files they will be used instead of what is available in the RCL.

A sample run of the above web application confirms this :

As you can see from the page title, heading and partial, RCL implementation is now overridden by web application's implementation.

If you wish you can put only *.cshtml files in the RCL and keep controllers and view models in the web application project.

That's it for now! Keep coding!!


Bipin Joshi is a software consultant, trainer, author and spiritual yoga mentor having 23+ years of experience in software development. He teaches online training courses in ASP.NET Core, Angular, and Design Patterns to individuals and small groups. He is a published author and has authored or co-authored books for Apress and Wrox press. Having embraced the Yoga way of life he also teaches Ajapa Yoga to interested individuals. To know more about him click here.

Get connected : Twitter  Facebook  Google+  LinkedIn

Posted On : 22 October 2018


Tags : ASP.NET ASP.NET Core MVC C# Visual Studio


Subscribe to our newsletter

Get monthly email updates about new articles, tutorials, code samples, and how-tos getting added to our knowledge base.