Reusable View Components in ASP.Net Core 1.1

In traditional ASP.Net MVC, we achieve reusable user interfaces through Partial Views. Starting with ASP.Net MVC Core, we have View components replacing the concept of Partial Views and Child only Actions. View Components can be in their own class libraries and can be referenced by multiple web projects. View Components are more independent as they are not coupled with Controllers. They can have their own business logic and data, there by supports rendering in chunks rather than to wait for entire response. In this tutorial we are going to see how to develop reusable View Components.

Lets get started by creating a .Net Core Class Library.

image

Lets add MVC dependency to the Project.json file. We also need to include Views as embed resources to the class library.

{
  "version": "1.0.0",

  "dependencies": {
    "NETStandard.Library": "1.6.1",
    "Microsoft.AspNetCore.Mvc": "1.1.0"
  },

  "frameworks": {
    "netstandard1.6": {
      "imports": "dnxcore50"
    }
  },

  "buildOptions": {
    "embed": "Views/**/*.cshtml"
  }
}

Lets add a strongly typed PersonDetailsViewModel class.

public class PersonDetailsViewModel
{
    public string Name { get; set; }
    public string Email { get; set; }
}

Now lets create a View Component by inhering from ViewComponent class. From now on we have to use PersonDetails as View component name.

public class PersonDetailsViewComponent : ViewComponent
{
    public IViewComponentResult Invoke(PersonDetailsViewModel personDetails)
    {
        return View(personDetails);
    }
}

Create a view with name Default.cshtml (place the view under Views –> Shared –> Components –> PersonDetails ) as shown below. As the project type is Class library, we do not have an option to add a cshtml to the project, just create the physical file with cshtml extension and include it in the project.

@model ViewComponents.PersonDetailsViewModel


<h3>Your name is @Model.Name</h3>
<br/>
<h3>Your email is @Model.Email</h3>

Project structure will be as shown below.

image

As we have the View Component ready, lets add it as a reference to our ASP.Net Core 1.1 project.

NOTE: Following tutorial has to be completed before proceeding with current tutorial Upgrading from ASP.Net Core 1.0 to ASP.Net Core 1.1.

Add ViewComponents and FileProviders to project.json dependency of the Web project.

"dependencies": {
  "Microsoft.NETCore.App": {
    "version": "1.1.0",
    "type": "platform"
  },
  /* Remaining Packages are omitted for code brevity */
  "Microsoft.Extensions.FileProviders.Embedded": "1.1.0",
  "ViewComponents": "1.0.0"
},

To use the View Component’s Views in Web Project, we need to configure Razor view engine in ConfigureServices() method of Startup class. First resolve the dependencies as shown below.

using Microsoft.Extensions.FileProviders;
using Microsoft.AspNetCore.Mvc.Razor;
using System.Reflection;

Then add the configuration as shown below.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    
    var assembly = typeof(ViewComponents.PersonDetailsViewComponent).GetTypeInfo().Assembly;            
    var embeddedFileProvider = new EmbeddedFileProvider(assembly, "ViewComponents");            
    services.Configure<RazorViewEngineOptions>(options =>
    {
        options.FileProviders.Add(embeddedFileProvider);
    });
}

Lets use the View Component in Index view.

<div class="row">
    @await Component.InvokeAsync("ViewComponents.PersonDetails", new ViewComponents.PersonDetailsViewModel{ Name = "Rami", Email = "r@r.com"})
</div>

Run the application and navigate to Index action, we should see below output.

image

That’s it for now, Happy Coding and Stay Tuned!!!

You may also like...

  • Mark Christian Perry

    Firstly, does it matter that this tutorial is out of date? there is no project.json which you refer to even after advising we read the upgrade to 1.1 post, which isn’t an issue as projects are now made as 1.1 anyway, meaning that right out of the gate this tutorial is inaccurate, to top it off the link is too as it goes on about project.json after upgrade, THERE IS NO PROJECT.JSON it is removed during upgrade and no longer used. There are also instructions missing about file structure, no where does it say where to put PersonDetailsViewComponent??
    Sadly, I needed to make use of another tutorial, just to finish this one; otherwise its a good example.and despite being told to read another post about upgrading, this tutorial was not upgraded.

  • Mark Christian Perry

    When trying to create default view:
    Severity Code Description Project File Line Suppression State
    Error CS0234 The type or namespace name ‘WebPages’ does not exist in the namespace ‘System.Web’ (are you missing an assembly reference?) 1_Views_Shared_Components_PersonDetails_Default.cshtml (Full stacktrace has been edited for original poster’s security).

  • ramiramilu

    Hi Mark, Thanks for your comment. I am little confused about the question you asked. PROJECT.JSON is not available starting from latest build of .NET CORE SDK (which is based on MSBuild). This tutorial is based on .Net Core Project.json SDK’s. At the time of writing this tutorial, .Net Core 1.1 is still using Project.json/XProj approach.

    One more important point which I wanted to make it clear is that this tutorial’s scope is to target .Net Core projects which are working with Project.json. There might be thousands of .Net Core applications out there which are not upgraded to latest MSBuild based SDK. So I have no intention to upgrade this tutorial to latest .Net Core SDK (MSBuild). To take your point, I would come up with new tutorial to target MSBuild (I cannot guarantee the time frame though) and latest .Net Core SDK and link that tutorial in here.

    Missing instructions about file structure? I already included an image depicting VS Project structure for ViewComponents class library.

  • ramiramilu

    Hi Mark, I am wondering why you are getting System.Web assemble error. Can you check if both of your class library and web projects are .Net Core based? Also I see that you are using VS 2017, are you trying to do the existing tutorial with new MSBuild .Net Core SDK?