One frequently requested scenario that ASP.NET Core 2.1 improves is building UI in reusable class libraries. With ASP.NET Core 2.1 you can package your Razor views and pages (.cshtml files) along with your controllers, page models, and data models in reusable class libraries that can be packaged and shared. Apps can then include pre-built UI components by referencing these packages and customize the UI by overriding specific views and pages.
To try out building Razor UI in a class library first install the .NET Core SDK for 2.1.0-preview1.
Create an ASP.NET Core Web Application by running dotnet new razor
or selecting the corresponding template in Visual Studio. The default template has fivestandard pages: Home, About, Contact, Error, and Privacy. Let’s move the Contact page into a class library. Add a .NET Standard class library to the solution and reference it from the ASP.NET Core Web Application.
We need to make some modifications to the class library .csproj file to enable Razor compilation. We need to set the RazorCompileOnBuild
, IncludeContentInPack
, and ResolvedRazorCompileToolset
MSBuild properties as well as add the .cshtml files as content and also a package reference to Microsoft.AspNetCore.Mvc. Your class library project file should look like this:
ClassLibrary1.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<ResolvedRazorCompileToolset>RazorSdk</ResolvedRazorCompileToolset>
<RazorCompileOnBuild>true</RazorCompileOnBuild>
<IncludeContentInPack>false</IncludeContentInPack>
</PropertyGroup>
<ItemGroup>
<Content Include="Pages\**\*.cshtml" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc" Version="2.1.0-preview1-final" />
</ItemGroup>
</Project>
For Preview1 making these project file modifications is a manual step, but in future previews we will provide a Razor MSBuild SDK (Microsoft.NET.Sdk.Razor) as well as project templates to handle these details for you.
Now we can add some Razor files to our class library. Add a Pages
directory to the class library project and move over the Contact page along with its page model (Contact.cshtml
, Contact.cshtml.cs
) from the web app project. You’ll also need to move over _ViewImports.cshtml
to get the necessary using statements.
Add some content to the Contact.cshtml
file so you can tell it’s being used.
@page
@model ContactModel
@{
ViewData["Title"] = "Contact";
}
<h2>@ViewData["Title"]</h2>
<h3>@Model.Message</h3>
<h2>BTW, this is from a Class Library!</h2>
Run the app and browse to the Contact page.
You can override views and pages from a class library in your app by putting the page or view at the same path in your app. For example, let’s add a _Message.cshtml
partial view that gets called from the contact page.
In the class library project add a Shared
folder under the Pages
folder and add the following partial view:
_Message.cshtml
<h2>You can override me!</h2>
Then call the _Message
partial from the contact page using the new partial tag helper.
Contact.cshtml
@page
@model ContactModel
@{
ViewData["Title"] = "Contact";
}
<h2>@ViewData["Title"]</h2>
<h3>@Model.Message</h3>
<h2>BTW, this is from a Class Library!</h2>
<partial name="_Message" />
Run the app to see that the partial is now rendered.
Now override the partial by adding a _Message.cshtml
file to the web app under the /Pages/Shared
folder.
_Message.cshtml
<h2>Overridden!</h2>
Rebuild and run the app to see the update.
Summary
By compiling Razor views and pages into shareable libraries you can reuse existing UI with minimal effort. Please give this feature a try and let us know what you think on GitHub. Thanks!