Custom Html Helper wird nicht verfügbar in der Ansicht (Razor / Asp.Net MVC3)

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

Frage

Ich versuche, einen Whitelist HTML Sanitizer mit HtmlAgilityPack zu implementieren. Ich möchte einen wiederverwendbaren Html Helper erstellen, der es mir erlaubt, ihn zu benutzen. Ich habe andere benutzerdefinierte HTML-Helfer, die ich benutze das funktioniert gut, aber aus irgendeinem Grund wird dieser nicht funktionieren. Jedes Mal, wenn ich versuche, es aus einer Sicht aufzurufen, kann die Sanitize-Methode nicht gefunden werden. Der Anruf, den ich versuche zu machen, ist in einer Teilansicht und sieht so aus:

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

Meine Html-Helferklasse:

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;
        }
    }
}

Credits für den Großteil dieses Codes gehen auf die Antwort in diesem Beitrag .

Dinge, die ich bereits überprüft habe:

  1. Der Namespace wurde in der Datei Web.Config korrekt definiert. (Ich weiß das auch, da andere im Namensraum bereits funktionieren)
  2. Habe einen sauberen Build des Projekts gemacht.
  3. Neustart von Visual Studio 2010

Gedanken darüber, warum ich die Methode nicht als Klasse bezeichnen kann?

Akzeptierte Antwort

Es sieht nicht so aus, als hättest du den HtmlHelper richtig erweitert.

Ihnen fehlt in Ihrer Funktionsdefinition Folgendes:

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

Lesen Sie diesen Beitrag zur Verwendung von Klassenerweiterungen, um Ihren Code mit dem UrlHelper zu vereinfachen



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum