Как проверить, что строка не содержит HTML, используя С#
Есть ли у кого-нибудь простой и эффективный способ проверки того, что строка не содержит HTML? В принципе, я хочу проверить, что определенные поля содержат только обычный текст. Я думал о поиске & но это легко использовать в виде простого текста. Другой способ - создать новый System.Xml.Linq.XElement, используя:
XElement.Parse("<wrapper>" + MyString + "</wrapper>")
и убедитесь, что XElement не содержит дочерних элементов, но это кажется немного тяжеловесным для того, что мне нужно.
Ответы
Ответ 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_token");
output = output.Replace("&", "&");
output = output.Replace("amp_token", "&");
// Convert less than to the less than entity (without messing up tags).
output = output.Replace("< ", "< ");
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 использовал "... в зависимости от того, насколько строго вы хотите, чтобы чек был..."