Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use a view inside ASP.NET Core custom Tag Helper?

I have been following this Microsoft article on writing custom Tag Helpers here.

Every where i see code where the element markup is hard coded in C#

Example (taken from the above link)

public override void Process(TagHelperContext context, TagHelperOutput output)
{
     output.TagName = "section";
     output.Content.SetHtmlContent(
        $@"<ul><li><strong>Version:</strong> {Info.Version}</li>
        <li><strong>Copyright Year:</strong> {Info.CopyrightYear}</li>
        <li><strong>Approved:</strong> {Info.Approved}</li>
        <li><strong>Number of tags to show:</strong> {Info.TagsToShow}</li></ul>");
     output.TagMode = TagMode.StartTagAndEndTag;
}

Instead of doing this, is there a way i can load the markup template from a cshtml file? (something similar to loading Partial Views)

My intention is to have individual cshtml files (one for each element type), so that i can style them easily. Also my C# would look clean!

Thanks,

James

like image 709
James Poulose Avatar asked Feb 10 '17 20:02

James Poulose


People also ask

What is the difference between tag helper vs HTML helper?

Tag Helpers are attached to HTML elements inside your Razor views and can help you write markup that is both cleaner and easier to read than the traditional HTML Helpers. HTML Helpers, on the other hand, are invoked as methods that are mixed with HTML inside your Razor views.

Can I use HTML tag helper of ASP NET framework in ASP.NET Core?

A Tag Helper Component is a Tag Helper that allows you to conditionally modify or add HTML elements from server-side code. This feature is available in ASP.NET Core 2.0 or later.

How would you use the input tag helper to bind an input element to an expression in a Razor view file?

The Input Tag Helper binds an HTML <input> element to a model expression in your razor view. The Input Tag Helper: Generates the id and name HTML attributes for the expression name specified in the asp-for attribute. asp-for="Property1.

How do I add Razor view?

Right-click on the Views/HelloWorld folder, and then Add > New Item. In the Add New Item - MvcMovie dialog: In the search box in the upper-right, enter view. Select Razor View - Empty.


2 Answers

You can create a partial view, and call it from your TagHelper class. For example:

<!-- Views/Shared/TagHelpers/MyList.cshtml -->
@model YourInfoClass
<ul>
    <li><strong>Version:</strong> @Model.Version</li>
    <li><strong>Copyright Year:</strong> @Model.CopyrightYear</li>
    <li><strong>Approved:</strong> @Model.Approved</li>
    <li><strong>Number of tags to show:</strong> @Model.TagsToShow</li>
</ul>

In your TagHelper:

[HtmlTargetElement("mylist")]
public class MyListTagHelper : TagHelper
{
    private HtmlHelper _htmlHelper;
    private HtmlEncoder _htmlEncoder;

    public MyListTagHelper(IHtmlHelper htmlHelper, HtmlEncoder htmlEncoder)
    {
        _htmlHelper = htmlHelper as HtmlHelper;
        _htmlEncoder = htmlEncoder;
    }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "section";
        output.TagMode = TagMode.StartTagAndEndTag;

        var partial = await _htmlHelper.PartialAsync("TagHelpers/MyList", Info);
        var writer = new StringWriter();
        partial.WriteTo(writer, _htmlEncoder);

        output.Content.SetHtmlContent(writer.ToString());
    }
}
like image 63
Métoule Avatar answered Sep 22 '22 18:09

Métoule


In this article from Tech Dominator http://blog.techdominator.com/article/using-html-helper-inside-tag-helpers.html they show how to do it in the simplest way that I found.

This is the example that appears in that article. I tested it and it works great:

using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Threading.Tasks;

namespace UsingCshtmlTemplatesInTagHelpers.TagHelpers
{
    public class Holder
    {
        public string Name { get; set; }
    }

    public class TemplateRendererTagHelper : TagHelper
    {
        [ViewContext]
        [HtmlAttributeNotBound]
        public ViewContext ViewContext { get; set; }

        private IHtmlHelper _htmlHelper;

        public TemplateRendererTagHelper(IHtmlHelper htmlHelper)
        {
            _htmlHelper = htmlHelper;
        }

        public override async Task ProcessAsync(TagHelperContext context
            , TagHelperOutput output)
        {
            (_htmlHelper as IViewContextAware).Contextualize(ViewContext);

            /*
             * Create some data that are going 
             * to be passed to the view
             */
            _htmlHelper.ViewData["Name"] = "Ali";
            _htmlHelper.ViewBag.AnotherName = "Kamel";
            Holder model = new Holder { Name = "Charles Henry" };

            output.TagName = "div";
            /*
             * model is passed explicitly
             * ViewData and ViewBag are passed implicitly
             */
            output.Content.SetHtmlContent(await _htmlHelper.PartialAsync("Template", model));
        }
    }
}
like image 42
Joe Salazar Avatar answered Sep 19 '22 18:09

Joe Salazar