Подтвердить что ты не робот

Как проверить, что строка не содержит HTML, используя С#

Есть ли у кого-нибудь простой и эффективный способ проверки того, что строка не содержит HTML? В принципе, я хочу проверить, что определенные поля содержат только обычный текст. Я думал о поиске & но это легко использовать в виде простого текста. Другой способ - создать новый System.Xml.Linq.XElement, используя:

XElement.Parse("<wrapper>" + MyString + "</wrapper>")

и убедитесь, что XElement не содержит дочерних элементов, но это кажется немного тяжеловесным для того, что мне нужно.

4b9b3361

Ответ 1

Я просто попробовал решение XElement.Parse. Я создал метод расширения в классе строк, чтобы я мог легко использовать код:

public static bool ContainsXHTML(this string input)
{
    try
    {
        XElement x = XElement.Parse("<wrapper>" + input + "</wrapper>");
        return !(x.DescendantNodes().Count() == 1 && x.DescendantNodes().First().NodeType == XmlNodeType.Text);
    }
    catch (XmlException ex)
    {
        return true;
    }
}

Одна из проблем, которые я обнаружил, заключалась в том, что простой текст ampersand и меньше символов вызывает исключение XmlException и указывает, что поле содержит HTML (что неверно). Чтобы исправить это, входная строка, прошедшая сначала, должна иметь амперсанды и меньше символов, преобразованных в их эквивалентные сущности XHTML. Для этого я написал другой метод расширения:

public static string ConvertXHTMLEntities(this string input)
{
    // Convert all ampersands to the ampersand entity.
    string output = input;
    output = output.Replace("&amp;", "amp_token");
    output = output.Replace("&", "&amp;");
    output = output.Replace("amp_token", "&amp;");

    // Convert less than to the less than entity (without messing up tags).
    output = output.Replace("< ", "&lt; ");
    return output;
}

Теперь я могу взять строку, отправленную пользователем, и проверить, что она не содержит HTML, используя следующий код:

bool ContainsHTML = UserEnteredString.ConvertXHTMLEntities().ContainsXHTML();

Я не уверен, что это доказательство пули, но я думаю, что это достаточно хорошо для моей ситуации.

Ответ 2

Следующее будет соответствовать любому соответствующему набору тегов. то есть <b> этот </b>

Regex tagRegex = new Regex(@"<\s*([^ >]+)[^>]*>.*?<\s*/\s*\1\s*>");

Следующее будет соответствовать любому одному тегу. т.е. <b> (его не нужно закрывать).

Regex tagRegex = new Regex(@"<[^>]+>");

Затем вы можете использовать его так

bool hasTags = tagRegex.IsMatch(myString);

Ответ 3

Вы можете обеспечить простой текст путем кодирования ввода с помощью HttpUtility.HtmlEncode.

Фактически, в зависимости от того, насколько строго вы хотите, чтобы проверка была, вы можете использовать ее, чтобы определить, содержит ли строка HTML:

bool containsHTML = (myString != HttpUtility.HtmlEncode(myString));

Ответ 4

Здесь вы идете:

using System.Text.RegularExpressions;
private bool ContainsHTML(string CheckString)
{
  return Regex.IsMatch(CheckString, "<(.|\n)*?>");
}

Это самый простой способ, поскольку элементы в скобках вряд ли встречаются естественным образом.

Ответ 5

Угловые скобки могут быть не единственной проблемой. Другие символы также могут быть потенциально опасными script инъекциями. Например, общий двойной дефис "-", который также может использоваться в SQL-инъекции. И есть другие.

На странице ASP.Net, если validateRequest = true в machine.config, web.config или директиве страницы, пользователь получит страницу с сообщением об ошибке "Потенциально опасное значение Request.Form было обнаружено у клиента", если обнаружен тег HTML или различные другие потенциальные атаки script -инъекции. Вероятно, вы хотите избежать этого и предоставить более элегантный, менее страшный опыт пользовательского интерфейса.

Вы можете проверить как открывающие и закрывающие теги < > с использованием регулярного выражения, так и разрешить текст, если только один из них затушевывает. Разрешить < или > , но не < за которым следует некоторый текст, а затем > , в этом порядке.

Вы можете разрешить угловые скобки и HtmlEncode текст, чтобы сохранить их, когда данные сохраняются.

Ответ 6

это также проверяет такие вещи, как < br/" > закрытые теги с дополнительными пробелами. список не содержит новых тегов html5.

internal static class HtmlExts
{
    public static bool containsHtmlTag(this string text, string tag)
    {
        var pattern = @"<\s*" + tag + @"\s*\/?>";
        return Regex.IsMatch(text, pattern, RegexOptions.IgnoreCase);
    }

    public static bool containsHtmlTags(this string text, string tags)
    {
        var ba = tags.Split('|').Select(x => new {tag = x, hastag = text.containsHtmlTag(x)}).Where(x => x.hastag);

        return ba.Count() > 0;
    }

    public static bool containsHtmlTags(this string text)
    {
        return
            text.containsHtmlTags(
                "a|abbr|acronym|address|area|b|base|bdo|big|blockquote|body|br|button|caption|cite|code|col|colgroup|dd|del|dfn|div|dl|DOCTYPE|dt|em|fieldset|form|h1|h2|h3|h4|h5|h6|head|html|hr|i|img|input|ins|kbd|label|legend|li|link|map|meta|noscript|object|ol|optgroup|option|p|param|pre|q|samp|script|select|small|span|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|ul|var");
    }
}

Ответ 7

Остерегайтесь использования метода HttpUtility.HtmlEncode, упомянутого выше. Если вы проверяете текст со специальными символами, но не HTML, он будет неправильно оценивать. Возможно, поэтому J c использовал "... в зависимости от того, насколько строго вы хотите, чтобы чек был..."