DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Coding
  3. Languages
  4. View Component or Tag Helper?

View Component or Tag Helper?

View components and tag helpers are nice features of ASP.NET Core that allow us to encapsulate some UI logic and avoid repeating the same code in different views.

Gunnar Peipman user avatar by
Gunnar Peipman
·
May. 23, 19 · Tutorial
Like (2)
Save
Tweet
Share
10.49K Views

Join the DZone community and get the full member experience.

Join For Free

Suppose you are working on an ASP.NET Core web application. To avoid havingn the views and layouts grow massively, you plan to separate some parts of these to independent components. This way you don't repeat code you wrote once. You find view components and tag helpers, but which one should you use?

The Difference Between View Components and Tag Helpers

It's important to understand what is what before doing any work.

  • View components are like partial views with no model binding. View components have a backing component class with the InvokeAsync() method. They support dependency injection like controllers do. Similar to controllers, they support multiple views.
  • Tag helpers are classes that allow server-side code to participate in the rendering of HTML elements. The most famous tag helper is probablythe  anchor tag helper that makes it possible to create MVC links using the <a> tag. Tag helpers support dependency injection but there's no support for external views. All markup is produced in tag helper code.

View component or tag helper? If it's something small, related to just few tags and no customizations are needed, then it's a tag helper; otherwise, it's view component.

Example: Assembly Version Tag Helper

I recently built a simple assembly version tag helper that I can use in projects where I have to display a web application version in  thefooter of all pages. The implementation is simple — just write out the version and that's it.

[HtmlTargetElement("AssemblyVersion", TagStructure = TagStructure.NormalOrSelfClosing)]
public class AssemblyVersionTagHelper : TagHelper
{
    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "";
        output.Content.Append(GetType().Assembly.GetName().Version.ToString());
    }
}

There's no point in going with a view component here, as there's no need for views.

Example: Pager View Component

A pager view component is a different beast and it comes with the need for custom markup. A pager may come with default markup but in different projects we may have different markup for a pager.

A tag helper doesn't have support for multiple views and wrapping markup inside C# code would be crazy. Just take a look at the following fragment of a view component view and think if you want to implement it in pure C# code.

<ul class="pagination">
    <li class="paginate_button page-item first" id="kt_table_1_first">
        <a tabindex="0" class="page-link" aria-controls="kt_table_1" href="@Html.Raw(urlTemplate + "1")">
            <i class="la la-angle-double-left"></i>
        </a>
    </li>
    <li class="paginate_button page-item previous" id="kt_table_1_previous">
        <a tabindex="0" class="page-link" aria-controls="kt_table_1" href="@Html.Raw(urlTemplate + (Model.CurrentPage-1))">
            <i class="la la-angle-left"></i>
        </a>
    </li>
    @for (var i = startIndex; i <= finishIndex; i++)
    {
        @if (i == Model.CurrentPage)
        {
            <li class="paginate_button page-item active">
                <a tabindex="0" class="page-link" aria-controls="kt_table_1" href="@Html.Raw(urlTemplate + i)">@i</a>
            </li>
        }
        else
        {
            <li class="paginate_button page-item ">
                <a tabindex="0" class="page-link" aria-controls="kt_table_1" href="@Html.Raw(urlTemplate + i)">@i</a>
            </li>
        }
    }
    <li class="paginate_button page-item next" id="kt_table_1_next">
        <a tabindex="0" class="page-link" aria-controls="kt_table_1" href="@Html.Raw(urlTemplate + (Math.Min(Model.CurrentPage + 1, Model.PageCount)))">
            <i class="la la-angle-right"></i>
        </a>
    </li>
    <li class="paginate_button page-item last" id="kt_table_1_last">
        <a tabindex="0" class="page-link" aria-controls="kt_table_1" href="@Html.Raw(urlTemplate + Model.PageCount)">
            <i class="la la-angle-double-right"></i>
        </a>
    </li>
</ul>

Of course we can come out with a base tag helper for pager, define protected virtual method to output markup, and create custom implementations based on it, but it's against the idea of why a tag helper was invented. Let's say it's anti-pattern.

Here is an example of a pager view component that supports custom views.

public class PagerViewComponent : ViewComponent
{
    public async Task<IViewComponentResult> InvokeAsync(PagedResultBase result, string viewName = "Default")
    {
        result.LinkTemplate = Url.Action(RouteData.Values["action"].ToString(), new { page = "{0}" });
 
        return await Task.FromResult(View(viewName, result));
    }
}

Compared to tag helpers, pager view components are easier to maintain as the view markup and view component code are separated.

Wrapping Up

View components and tag helpers are nice features of ASP.NET Core that allow us to encapsulate some UI logic and avoid repeating the same code in different views. We can use view components and tag helpers in shared projects and libraries. Tag helpers are for extending HTML elements with server-side logic. View components support custom views like controllers do and they are for cases when a component has more markup than just a few HTML tags.

Dependency injection Pager Web application ASP.NET Core IT Anti-pattern HTML Implementation Assembly (CLI)

Published at DZone with permission of Gunnar Peipman, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • The Role of Data Governance in Data Strategy: Part II
  • What Was the Question Again, ChatGPT?
  • Taming Cloud Costs With Infracost
  • The Importance of Delegation in Management Teams

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: