Using a View Component to Create a Menu in ASP.NET Core

We wanted to include a menu component that is dynamically generated depending on the parameters and current route while creating our latest web application. 

I looked into the idea of partials in ASP.NET Core, also if  these are really perfect for reusing static markup, they’re not so perfect for building dynamic, data-driven content like a dynamic menu does.

Wherever it is part of your requirement  to reuse dynamic and / or data driven content, then the most appropriate design approach is to use a ViewComponent. From this page (Microsoft documentation)

After observing Partial Views, and View Components, I discovered that ViewComponents don’t have to rely on existing data. For instance, you can just  make an asynchronous call to a server side method such as this:

@await Component.InvokeAsync(“MenuItems”, 1234)

 

As stated by Microsoft documentation, view components share similarities with  partial views, but they are much more efficient. View components don’t always use model binding, and are dependent on the data provided when called. A view component:

– Renders a bit as opposed to the whole response.
– Contains the exact separation-of-concerns and testability benefits found between a controller and view.
– Can have  business logic and parameters .
– Is normally invoked from a layout page.

View components are intended anywhere you’ve got reusable rendering logic that’s too tedious for a partial view, like:

– Dynamic navigation menus

Tag cloud (Database is questioned here)

– Login page panel

Now, our menu tree structure is handled by a ViewComponent. All the business logic for building a user-specific menu is contained within the ViewComponent, and the ViewComponent returns the menu tree structure. This is then shown by the Razor Page that calls the ViewComponent. When you call a view component method, you don’t have to pass parameters, and you don’t have to pass a view model. However, with Partials, you need to pass data (a view model), at the time you want to render the Partial view, so you need to have your data ready before hand, making it tightly coupled to your existing view(s).

There are also many other benefits such as:

– Confines the basic business logic for a Razor Page in a separate component
– Allows the business logic to be unit-tested
– Allows for the UI component to be reused across different forms, essentially acting like an independent view
– Leads to cleaner code together with separation of concerns

Below is a typical View Component itself:


The ViewComponent calls other form of methods to basically generate the menu. and In this case it’s just a list of Parent -> child mapped menu items  which is included here for your reference:


The moment you have your ‘hierarchical’ list of Menu objects, just change it back to your view as shown inside the InvokeAsync() method. In this case, the view, just iteratively shows the menu items according to the parent child relationships within your menu records:


This is returned wrapped inside an instance of IViewComponentResult, which is one of the supported result types returned from a ViewComponent.

 Call to invoke the ViewComponent from the layout page appears just like this :


@await Component.InvokeAsync(“Menu”, new { cbaId = ViewBag.Id })

I’ve utilized the ViewBag in a scenario like this to pass an ID to the ViewComponent, so there is some context of what to show. You should also notice that within the ViewComponent that I recovered the current Route, and use it, along with the Id above to ascertain what menu items to load.

The end result will look like:


What do you you notice? You can see the ordering is correct, and along with using Font Awesome icons, a nice collapsible menu is produced. when you click on the Create New button, it  runs custom Javascript to most likely create something:


The rest of the items are route Url’s and they were all created from the MenuHelper class. I made use of the basic ASP.NET core application as a benchmark and ‘wrapped’ my menu components around it.

I created the total dynamic menuing system very rapidly. And, it’s essentially independent of other views and partial views within your system. This can be reused effortlessly by copying and pasting all of my code into your mvc / web application. This is a typical real world example that solves very real problems with modern application development. Having independent, simply testable modules like this ensures your applications are far less likely to cause problems in a production environment.

Source Code

Categories:

6 Responses

  1. Adin says:

    Hi,
    You wrote “This can be reused simply by cutting and pasting all of my code into your application”. Where can your code be downloaded or copied from? I only see some screenshots of code in the article.

    Thanks!

  2. Anthony says:

    Hi

    Nice article.
    What’s happening in the MenuHelper class ?

  3. bob says:

    Hi,

    There is no link to any source code for this? The ‘CodeProject’ link does not contain source code related to this article. Is there a Github project link?

Leave a Reply

Your email address will not be published. Required fields are marked *