7

So I was searching for a good way in ASP.Net Core to create some "controls" that render into a view. So far I found there are 3 options, and I wanted to get some feedback on them.

  1. ViewComponents: These are like mini controllers and use methods like actions to render from a razor page (view). I believe they can have self-contained logic so there's no dependency on any parent view model.

  2. EditorTemplate/DisplayTemplate folders: These exist under "Views/Shared/" and could be pulled into a view by passing a model property to them (using DisplayFor() or EditorFor()).

  3. @inject for ASP.Net Core: Allows injecting a type into a view (I have no idea if a partial view can be associated?).

  4. I'm leaving out the ability to include partial views directly, as it is not my intent for the control system I'm porting over.

  5. Tag Helpers - it's possible to inject the current view context and build controls from these also.

In an older ASP.NET MVC app I had some controls that rendered from the templates (#2). However for .Net Core, I'm contemplating on possibly using ViewComponents instead (which seem more powerful) for rendering associated razor views (the controls basically just wrap razor views). For the moment I'll be experimenting with converting to ViewComponents, but would love some advice on the matter, thanks.

2

Use ViewComponent if you have some business logic to run. It supports Separation of Concerns (SoC) principle. You can inject parameters to ViewComponent class from view (use razor .cshtml file). ViewComponent views can be found in Views/Shared/Components. It can be strongly-typed. ViewComponent use asynchronous method calls, so users doesn't have to wait for all of the content of an entire page to load. Moreover, ViewComponent can be invoked as Tag Helper: you need to add your ViewCompenent as Tag Helper using @addTagHelpers directive. This feature gives developer editor support in the razor editor template.

Use Editor/Display Template when editing or displaying certain types or classes. For example, you want to specify that Product object must appear with specification table. It preserves DRY principle in your MVC application. It can be used as partial view that is model bound to the object it wants to display.

0

My approach is as follows...

  1. Use the ViewComponent to encapsulate the business logic of how to retrieve the models to be displayed
  2. If the target view is simple and/or single put the html here directly, otherwise use a DisplayTemplate to render the model

Rationale is I still get separation of concerns between the business logic and the rendering.

As a practical example take something like a context specific menu structure; the ViewComponent can determine which menus to show and the DisplayTemplate then can render each one.

  • Be careful of using these to load data. An employee of mine did that and later when we wanted to build a REST API for AJAX (for instance, if someone wanted to use Angular), the logic was then in the API and NOT the components. ;) If not using a REST API for your site (which is common today), then the components are best used for rendering only by passing data to them by controller actions and returning the result. In the end, I decided to use Tag Helpers with an injected action context to build my controls as tags in the views. It looks much cleaner in the end. ;) – James Wilkins May 14 '18 at 20:20
  • I inject the api service into the ViewComponent to actually acquire the data - if we need the same logic returning the target html e.g. to use ajax to refresh the component, then I expose it via a controller method. – Paul Hatcher May 15 '18 at 10:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.