如何在ASP.NET ValidationAttribute中白名单指定HTML标签?
实现带白名单的HTML标签ValidationAttribute
我之前在项目里正好遇到过一模一样的需求,当时也是从拦截所有HTML标签改成允许指定白名单标签,给你分享一下完善后的实现方案,应该能直接用:
核心思路
不能简单用字符串包含判断,因为HTML标签可能有各种写法(比如大小写、带属性、自闭合),所以我们用正则表达式提取输入中的所有HTML标签名,然后逐一检查是否在白名单内——只要有一个不在白名单的标签,就验证失败。
完整的ValidationAttribute实现
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Text.RegularExpressions; public class AllowedHtmlTagsAttribute : ValidationAttribute { // 允许的标签白名单,可通过特性参数配置 public string[] AllowedTags { get; set; } = Array.Empty<string>(); // 匹配HTML标签的正则,能提取标签名(忽略大小写、属性、自闭合) private static readonly Regex TagRegex = new Regex(@"<\/?([a-z0-9]+)\b[^>]*>", RegexOptions.IgnoreCase | RegexOptions.Compiled); protected override ValidationResult IsValid(object value, ValidationContext validationContext) { if (value == null) { // 空值直接通过,如需必填请搭配[Required]特性 return ValidationResult.Success; } var input = value.ToString(); if (string.IsNullOrWhiteSpace(input)) { return ValidationResult.Success; } // 提取所有匹配到的标签名 var matches = TagRegex.Matches(input); var invalidTags = new HashSet<string>(StringComparer.OrdinalIgnoreCase); foreach (Match match in matches) { var tagName = match.Groups[1].Value.Trim(); // 检查当前标签是否在白名单内 if (!Array.Exists(AllowedTags, t => t.Equals(tagName, StringComparison.OrdinalIgnoreCase))) { invalidTags.Add(tagName); } } if (invalidTags.Count > 0) { return new ValidationResult($"输入包含不允许的HTML标签:{string.Join(", ", invalidTags)}"); } return ValidationResult.Success; } }
使用方式
在你的模型属性上直接标记这个特性,指定允许的标签即可:
public class UserInputModel { [AllowedHtmlTags(AllowedTags = new[] { "strong", "p", "br" })] public string Content { get; set; } }
注意事项
- 大小写兼容:正则和标签比较都用了忽略大小写,所以
<STRONG>、<P>这类写法也会被允许; - 支持带属性的标签:比如
<p class="text-red">内容</p>会被正确识别为p标签,只要在白名单里就会通过; - 自闭合标签:比如
<br />也能被提取到br标签名,白名单包含br就会允许; - 空值处理:空字符串或null会直接通过验证,如果需要强制必填,请配合
[Required]特性一起使用; - 正则优化:如果你的场景里有特殊标签(比如自定义标签),可以调整正则表达式,但当前的正则已经覆盖了绝大多数常见HTML标签的情况。
这样实现后,输入<strong> hello world </strong> <p>hello </p>会验证通过,而<div>hello</div>或者<h1>标题</h1>这类不在白名单的标签就会抛出错误啦。
内容的提问来源于stack exchange,提问作者zm10
相关产品推荐
相关产品推荐

