Custom Html Helper no está disponible en la vista (Razor / Asp.Net MVC3)

asp.net-mvc asp.net-mvc-3 c# html-agility-pack html-helper

Pregunta

Estoy tratando de implementar un Sanitizer HTML de la lista blanca usando HtmlAgilityPack . Quiero crear un ayudante HTML reutilizable que me permita usarlo. Tengo otros ayudantes de Html personalizados que estoy usando que funcionan muy bien, pero por alguna razón este no funcionará. Cada vez que trato de llamarlo desde una vista, no puede encontrar el método de desinfección. La llamada que estoy tratando de hacer está en una vista parcial y se ve así:

@Html.Raw(Html.Sanitize(Model.Body))

Mi clase Html Helper:

using System;
using System.Text;
using System.Web.Mvc;
using System.Collections.Generic;
using System.Linq;
using HtmlAgilityPack;

namespace ProjectX.WebUI.HtmlHelpers
{
    public static class HtmlSanitizeHelpers
    {
        private static readonly IDictionary<string, string[]> Whitelist;
        private static List<string> DeletableNodesXpath = new List<string>();

        static HtmlSanitizeHelpers()
        {
            Whitelist = new Dictionary<string, string[]> {
                { "a", new[] { "href" } },
                { "strong", null },
                { "em", null },
                { "blockquote", null },
                { "b", null},
                { "p", null},
                { "ul", null},
                { "ol", null},
                { "li", null},
                { "div", new[] { "align" } },
                { "strike", null},
                { "u", null},                
                { "sub", null},
                { "sup", null},
                { "table", null },
                { "tr", null },
                { "td", null },
                { "th", null }
                };
        }

        public static MvcHtmlString Sanitize(string input)
        {
            if (input.Trim().Length < 1)
                return MvcHtmlString.Empty;
            var htmlDocument = new HtmlDocument();

            htmlDocument.LoadHtml(input);            
            SanitizeNode(htmlDocument.DocumentNode);
            string xPath = HtmlSanitizeHelpers.CreateXPath();

            return MvcHtmlString.Create(StripHtml(htmlDocument.DocumentNode.WriteTo().Trim(), xPath));
        }

        private static void SanitizeChildren(HtmlNode parentNode)
        {
            for (int i = parentNode.ChildNodes.Count - 1; i >= 0; i--)
            {
                SanitizeNode(parentNode.ChildNodes[i]);
            }
        }

        private static void SanitizeNode(HtmlNode node)
        {
            if (node.NodeType == HtmlNodeType.Element)
            {
                if (!Whitelist.ContainsKey(node.Name))
                {
                    if (!DeletableNodesXpath.Contains(node.Name))
                    {                       
                        //DeletableNodesXpath.Add(node.Name.Replace("?",""));
                        node.Name = "removeableNode";
                        DeletableNodesXpath.Add(node.Name);
                    }
                    if (node.HasChildNodes)
                    {
                        SanitizeChildren(node);
                    }                  

                    return;
                }

                if (node.HasAttributes)
                {
                    for (int i = node.Attributes.Count - 1; i >= 0; i--)
                    {
                        HtmlAttribute currentAttribute = node.Attributes[i];
                        string[] allowedAttributes = Whitelist[node.Name];
                        if (allowedAttributes != null)
                        {
                            if (!allowedAttributes.Contains(currentAttribute.Name))
                            {
                                node.Attributes.Remove(currentAttribute);
                            }
                        }
                        else
                        {
                            node.Attributes.Remove(currentAttribute);
                        }
                    }
                }
            }

            if (node.HasChildNodes)
            {
                SanitizeChildren(node);
            }
        }

        private static string StripHtml(string html, string xPath)
        {
            HtmlDocument htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(html);
            if (xPath.Length > 0)
            {
                HtmlNodeCollection invalidNodes = htmlDoc.DocumentNode.SelectNodes(@xPath);
                foreach (HtmlNode node in invalidNodes)
                {
                    node.ParentNode.RemoveChild(node, true);
                }
            }
            return htmlDoc.DocumentNode.WriteContentTo(); ;
        }

        private static string CreateXPath()
        {
            string _xPath = string.Empty;
            for (int i = 0; i < DeletableNodesXpath.Count; i++)
            {
                if (i != DeletableNodesXpath.Count - 1)
                {
                    _xPath += string.Format("//{0}|", DeletableNodesXpath[i].ToString());
                }
                else _xPath += string.Format("//{0}", DeletableNodesXpath[i].ToString());
            }
            return _xPath;
        }
    }
}

Los créditos para la mayoría de este código van a la respuesta en esta publicación .

Cosas que ya he comprobado:

  1. El espacio de nombres se ha definido correctamente en el archivo Web.Config. (También sé esto porque otros en el espacio de nombres ya funcionan)
  2. Han hecho una compilación limpia del proyecto.
  3. Se reinició Visual Studio 2010.

¿Pensamientos sobre por qué parece que no puedo llamar el método de la clase?

Respuesta aceptada

No parece que hayas extendido correctamente el HtmlHelper.

Te falta lo siguiente en tu definición de función:

public static MvcHtmlString Sanitize(this HtmlHelper helper, string input)

Echa un vistazo a esta publicación en Uso de las extensiones de clase para simplificar tu código con UrlHelper



Related

Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué
Licencia bajo: CC-BY-SA with attribution
No afiliado con Stack Overflow
¿Es esto KB legal? Sí, aprende por qué