Dominic Burford - Professional Profile
|While developing our new web application, we wanted to take a component-based approach and build up the user-interface from small, discreet UI components. So instead of having monolithic Razor Pages containing many different controls, we thought it would be a far better design approach to develop the UI from smaller, discreet components that we could then re-use in other parts of the application.
I initially looked into the concept of partials in ASP.NET Core, and while these are great for re-using static markup, they're not so great for building dynamic, data-driven content such as menus (which would be the first component I would in fact be developing).
Where your requirement is to re-use dynamic and / or data driven content, then the correct design approach is to use a ViewComponent. From the Microsoft documentation[^]
I won't copy the entire list here, I've posted the link to the documentation so you can have a read of it for yourself.
Quote:New to ASP.NET Core MVC, view components are similar to partial views, but they're much more powerful. View components don't use model binding, and only depend on the data provided when calling into it. A view component:
- Renders a chunk rather than a whole response.
- Includes the same separation-of-concerns and testability benefits found between a controller and view.
- Can have parameters and business logic.
- Is typically invoked from a layout page.
View components are intended anywhere you have reusable rendering logic that's too complex for a partial view, such as:
- Dynamic navigation menus // bingo!! this is what we're looking for!!
So 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 displayed by the Razor Page that is associated with the ViewComponent.
So building our application's menu is encapsulated in a re-usable, discreet and unit-testable ViewComponent. Going forwards, we will use ViewComponent's for all of our UI components, and build up our Razor Pages from multiple ViewComponents.
This gives us huge benefits.
- Encapsulate the underlying business logic for a Razor Page in a separate component
- Allow for the business logic to be unit-tested
- Allow for the UI component to be re-used across different forms
- Leads to cleaner code with separation of concerns
Here's a (very) simplified example of how we've used a ViewComponent to build our menu tree structure. Note that all exception handling, logging etc has been removed for brevity.
public class MenuItemsViewComponent: ViewComponent
public async Task<IViewComponentResult> InvokeAsync(int parentId, string email)
var response = await new MenuServices().GetModulesItemsForUser(parentId, email);
}The ViewComponent calls one of our ASP.NET Web API services to retrieve the menu tree specified menu level and user. It then returns this wrapped inside an instance of IViewComponentResult, which is one of the supported result types returned from a ViewComponent.
Here is the (very) simplified Razor Page that displays the output from the ViewComponent. Note that all styling has been removed for brevity.
@if (Model != null && Model.MenuItems != null && Model.MenuItems.Any())
foreach (var menuitem in Model.MenuItems)
}And finally here's how we invoke the ViewComponent from our layout page.
@await Component.InvokeAsync("MenuItems", 0, "email@example.com")I am very impressed with the ViewComponent concept. From a design point-of-view, it is the correct approach if you are building forms that contain any sort of dynamic content. By allowing for clean separation of concerns and supporting unit testing, you can ensure your applications are far more robust and less likely to fail in production. These are just a couple of reasons why you should consider using ViewComponent's in your own ASP.NET Core 2.0 applications. Why not give them a try.
"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - C.A.R. Hoare
General News Suggestion Question Bug Answer Joke Praise Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
Copyright © CodeProject
All Rights Reserved.