Tag Helpers Extending existing helper- is this possible?

72 Views Asked by At

So I am working with custom tag helpers and i ran into a (possible) problem. I have JSON files containing some embedded HTML mark up (img, links) mostly. I have written a custom Image Tag Helper to alter the attributes. However I noticed that html rendered through Html.Raw() will not invoke the tag helper.

Question: Is it possible to add an extension method to Html.Raw(), if so how?

Or am i doing something wrong with my tag helpers and the image tag helper should in fact be invoked by the rendered elements?

Also the tag helper does work for standard rendered images.

some code

viewimports

@using projectname.de
@using projectname.de.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
@addTagHelper *, projectname.de

Tag helper

[HtmlTargetElement("img", TagStructure = TagStructure.WithoutEndTag)]
public class ImageTagHelperExtension : TagHelper
{        
    public string? Src { get; set;  }
    public string? Alt { get; set; }
    public override void Process(TagHelperContext context, TagHelperOutput output)
    {                        
        if (!string.IsNullOrEmpty(Src))
        {                
            output.Attributes.Add("src", $"https://www.sitenames.com/{Src.ToLower()}");                
        }
        if (string.IsNullOrEmpty(Alt))
        {
            output.Attributes.Add("alt", "image alt tag");
        }           
    }
}
1

There are 1 best solutions below

1
Rena On BEST ANSWER

Is it possible to add an extension method to Html.Raw(), if so how?

Html.Raw() in ASP.NET Core does not process custom tag helpers.

You can preprocess the HTML content on the server before sending it to the view by using HtmlAgilityPack.

  1. Install HtmlAgilityPack

    Install-Package HtmlAgilityPack
    
  2. Create a static method to process HTML

    public static class HtmlContentProcessor
    {
        public static string ProcessHtml(string htmlContent)
        {
            var htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(htmlContent);
    
            var imgNodes = htmlDoc.DocumentNode.SelectNodes("//img");
    
            if (imgNodes != null)
            {
                foreach (var img in imgNodes)
                {
                    var src = img.GetAttributeValue("src", string.Empty);
                    if (!string.IsNullOrWhiteSpace(src))
                    {
                        // Modify the src attribute
                        img.SetAttributeValue("src", $"https://www.perle.com/{src.ToLower()}");
                    }
                    var alt = img.GetAttributeValue("alt", string.Empty);
                    if (string.IsNullOrWhiteSpace(alt))
                    {
                        img.SetAttributeValue("alt", "image alt tag");
                    }
                }
            }
    
            return htmlDoc.DocumentNode.OuterHtml;
        }
    }
    
  3. Use the method in your razor view

    @model string
    
    @{
        var processedContent = HtmlContentProcessor.ProcessHtml(Model);
    }
    
    @Html.Raw(processedContent)
    
  4. Backend code

    public async Task<IActionResult> Index()
    {
        string data = "<img src=\"Images/MyImage.jpg\">";
        return View("Index", data);
    }