View code reuse techniques in ASP.NET MVC

data: 19 sierpnia, 2014
czas czytania: 7 min
autor: Krzysztof Szabelski

Every good software developer knows that repeating himself in code is a smell. Copy-paste method turns against us as soon as we need to modify copied code. ASP.NET MVC and Razor View Engine give us multiple ways to avoid repetitions in views code, however too many options may make developers confused in what should be used where. In this post I’m trying to compare all of them and point out their typical usage. To make this review complete, I’m providing solution with examples of all mechanisms usage, it can be found at my GitHub: https://github.com/szabl/AspNetViewsCodeReuseExamples

Overview

[table id=10 /]

HTML Helpers

Overview

This method is well known due to the fact that standard library contains many predefined, commonly used Helpers such as:

@Html.TextBox("name");

There is no magic in here, those are ordinary functions taking parameters and returning HTML as a string. According to convention, they are defined as Extention Methods for HtmlHelper class or simply as a static method.

Remarks

This convention is simple and is great for short, repeatable HTML templates. However, when amount of HTML to produce grows, concatenating strings in C# code becomes highly unreadable. What is more, as static methods are global to the whole application, this technique is not suggested to create elements used only on single view. When helper is defined as an extension method to HtmlHelper, it has access to View specific information through this object properties (ViewContext, ViewBag, etc.) Note: If you use Razor View Engine, HTML helpers should return implementation of IHtmlString rather than plain string, otherwise all special characters are encoded.

Examples

See examples on Github:

3rd party articles:

Display/Editor Template

Overview

This technique enables us to create templates for presenting and editing particular types of data. It can be both simple types as well as complex ones. After defining the template (here, for the User class) we can use it through:

@Html.DisplayFor(m => m.User)

Remarks

The usage of this mechanisms is quite obvious and limited. It will be a perfect choice if we use a standard display or edit template for particular data types. There is possibility of creating global templates as well as the ones with limited scope. Using default conventions, the former should be put in the Shared folder, whereas the latter in a specific view one. What is more, a given type can have several templates. To use template, other than the default one, it is necessary to provide name of the file containing its definition. Default template is the one defined in the file which name is similar to the type name.

Examples

See examples on Github:

3rd party articles:

Razor Helpers

Overview

From the usage point of view, the mechanism is similar to Html helpers. However, when it comes to implementation it is totally different. Instead of C# code, from which we generate HTML string, we write HTML code in cshtml file and use Razor to insert C# logic.

Remarks

Helpers can be both local for one view, then we can define it in the same file, and global, available in the whole web application. In order to do that, it is necessary to put helper in cshtml file, in App_Code folder. It is a perfect solution if we need to use similar but rather small part of view in many places. This method is available only if we use Razor View Engine. In other cases it can be replaced with a little bit „heavier” Partial Views mechanism.

Examples

See examples on Github:

3rd party articles:

Partial View

Overview

This mechanism allows to render a different view and insert its output in place of the call.

Remarks

It may not be clear at first look, but it is very similar to public Razor helpers. Partials, however, are „heavier”, because each of them require new file. For this reason, they are suggested to encapsulate bigger parts of views than Razor helpers. What is more, it is great way to break a very long view into smaller pieces. It is similar technique to extract method refactoring. If we look closer, technically, they are similar to Display Templates, difference is more in purpose of use.

Examples

See examples on Github:

3rd party articles:

Child Action

Overview

The technique of calling a controller action from view, the result of which is a string or Partial View that after rendering is inserted in place of the call. This action is no different than regular ones, it can gain access to the lower layers of an application and freely process data. Using attribute ChildActionOnly we can limit it, so that it can be only called as Child Action.

Remarks

A tool mostly for creating independent, fully encapsulated controls, which takes small amount of data as a parameters and make use of data sources and business logic to produce output. Those controls should be independent from the place they are called. Their usage are similar to User Controls from ASP.NET WebForms, with one difference, they fit better to MVC philosophy. Controller action should return the view with the use of PartialView method, so that it doesn’t use a default layout.

Examples

See examples on Github:

3rd party articles:

Layouts

Overview

Layout is usually a file containing html and body tags as well as html elements common to all views. To define placeholders for page-specific content use:

  • @RenderBody – to mark place where all view content is rendered,
  • @RenderSection – to mark place where specific, named section is rendered.

View layout can be defined by setting it’s Layout property:

@{ Layout = "~/Views/Shared/_Layout.cshtml"; }

This can be done either explicitly in view or in _ViewStart.cshtml file, which is executed before any other view file when calling controller’s View() method.

Remarks

Usually, there is a default layout, defined in Views/Shared/_Layout.cshtml file and it is made default in _ViewStart file in Views folder. View with non default layout can define it inline, or use _ViewStart.cshtml file local to specific folder. By setting second parameter of @RenderSection to false it can be made optional, so Views that don’t need it, can ignore it. Layouts can be nested. See example and external articles for more information.

Examples

See examples on Github:

3rd party articles:

MVC View UserControl

Overview

The mechanism allowing the usage of user controllers from ASP.NET WebForms in ASP.NET MVC.

Remarks

I can’t find sources confirming this, but probably the mechanism was put in a ASP.NET MVC just to facilitate the migration of pages from WebForms to MVC and should be used only for this purpose. It doesn’t fit to MVC philosophy, that is why if we create something from the scratch, it is better to choose one of the above mentioned methods.

Examples

3rd party articles:

Summary

ASP.NET MVC has various mechanisms that help us follow DRY principle. However, the big variety comes with little mess, worst we can do is to pick one tool and use it for everything. Since we have such a great number of options let’s apply them where they suits best. Be prepared for that by trying them out now.

Newsletter IT leaks

Dzielimy się inspiracjami i nowinkami z branży IT. Szanujemy Twój czas - obiecujemy nie spamować i wysyłać wiadomości raz na dwa miesiące.

Subscribe to our newsletter

Administratorem Twoich danych osobowych jest Future Processing S.A. z siedzibą w Gliwicach. Twoje dane będziemy przetwarzać w celu przesyłania cyklicznego newslettera dot. branży IT. W każdej chwili możesz się wypisać lub edytować swoje dane. Więcej informacji znajdziesz w naszej polityce prywatności.

Subscribe to our newsletter

Administratorem Twoich danych osobowych jest Future Processing S.A. z siedzibą w Gliwicach. Twoje dane będziemy przetwarzać w celu przesyłania cyklicznego newslettera dot. branży IT. W każdej chwili możesz się wypisać lub edytować swoje dane. Więcej informacji znajdziesz w naszej polityce prywatności.