提问人:Ben Mills 提问时间:10/15/2008 更新时间:5/19/2020 访问量:53563
如何使用 C 验证字符串是否不包含 HTML#
How to validate that a string doesn't contain HTML using C#
问:
有没有人有一种简单有效的方法来检查字符串是否不包含 HTML?基本上,我想检查某些字段是否只包含纯文本。我想过寻找<字符,但这可以很容易地在纯文本中使用。另一种方法是使用以下方法创建新的 System.Xml.Linq.XElement:
XElement.Parse("<wrapper>" + MyString + "</wrapper>")
并检查 XElement 是否不包含子元素,但对于我需要的东西来说,这似乎有点重量级。
答:
以下内容将与任何匹配的标签集匹配。即 <b>this</b>
Regex tagRegex = new Regex(@"<\s*([^ >]+)[^>]*>.*?<\s*/\s*\1\s*>");
以下内容将与任何单个标签匹配。即 <b>(它不必关闭)。
Regex tagRegex = new Regex(@"<[^>]+>");
然后,您可以像这样使用它
bool hasTags = tagRegex.IsMatch(myString);
评论
给你:
using System.Text.RegularExpressions;
private bool ContainsHTML(string checkString)
{
return Regex.IsMatch(checkString, "<(.|\n)*?>");
}
这是最简单的方法,因为括号中的项目不太可能自然出现。
评论
尖括号可能不是您唯一的挑战。其他字符也可能是可能有害的脚本注入。比如常见的双连字符“--”,也可以用在SQL注入中。还有其他人。
在 ASP.Net 页上,如果 machine.config、web.config 或 page 指令中的 validateRequest = true,则在检测到 HTML 标记或其他各种潜在的脚本注入攻击时,用户将收到一个错误页面,指出“从客户端检测到潜在危险的 Request.Form 值”。您可能希望避免这种情况,并提供更优雅、更不可怕的 UI 体验。
您可以使用正则表达式测试开始和结束标记<>,如果只有一个文本占用,则允许文本。允许<或>,但不允许<后跟一些文本,然后按此顺序>。
您可以允许使用尖括号,并在保留数据时对文本进行 HtmlEncode 编码以保留它们。
评论
您可以通过使用 HttpUtility.HtmlEncode 对输入进行编码来确保纯文本。
事实上,根据你希望检查的严格程度,你可以用它来确定字符串是否包含 HTML:
bool containsHTML = (myString != HttpUtility.HtmlEncode(myString));
评论
我刚刚尝试了我的 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;
}
}
我发现的一个问题是纯文本 & 号和小于字符会导致 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();
我不确定这是否是防弹的,但我认为这对我的情况来说已经足够了。
评论
使用上面提到的 HttpUtility.HtmlEncode 方法时要小心。如果您检查某些带有特殊字符的文本,而不是 HTML,则它将错误地计算。也许这就是为什么 J c 使用“......取决于你希望检查的严格程度......”
这还会检查诸如< 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");
}
}
评论