能否通过C#类特性实现HTML输入的自动清理?
如何通过特性实现C#模型属性的自动HTML清理?
通常清理HTML输入会用到HtmlSanitizer库,基础用法示例如下:
var sanitizer = new HtmlSanitizer(); var sanitized = sanitizer.Sanitize(model.htmlInput);想问能不能像
[Required]或[Range(1, Int32.MaxValue)]这类模型验证特性一样,在C#类的属性上声明[HtmlSanitizer]特性,实现HTML输入自动清理并传递处理后的值?
当然可以实现,你需要自定义一个结合HtmlSanitizer的模型绑定特性,利用ASP.NET Core的模型绑定机制来自动处理属性值。下面是具体实现方案:
1. 自定义HtmlSanitizeAttribute特性
创建一个继承自Attribute并实现IModelBinder接口的特性类,在绑定过程中完成HTML清理:
using HtmlSanitizer; using Microsoft.AspNetCore.Mvc.ModelBinding; using System; using System.Threading.Tasks; public class HtmlSanitizeAttribute : Attribute, IModelBinder { // 可自定义允许的标签、属性,默认使用库的预设值 public string[] AllowedTags { get; set; } = HtmlSanitizer.DefaultAllowedTags; public string[] AllowedAttributes { get; set; } = HtmlSanitizer.DefaultAllowedAttributes; public Task BindModelAsync(ModelBindingContext bindingContext) { if (bindingContext == null) throw new ArgumentNullException(nameof(bindingContext)); // 获取原始输入值 var valueProviderResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName); if (valueProviderResult == ValueProviderResult.None) return Task.CompletedTask; bindingContext.ModelState.SetModelValue(bindingContext.ModelName, valueProviderResult); var rawValue = valueProviderResult.FirstValue; if (string.IsNullOrEmpty(rawValue)) { bindingContext.Result = ModelBindingResult.Success(null); return Task.CompletedTask; } // 初始化 sanitizer 并应用自定义规则 var sanitizer = new HtmlSanitizer { AllowedTags = AllowedTags, AllowedAttributes = AllowedAttributes }; var sanitizedValue = sanitizer.Sanitize(rawValue); // 将清理后的值绑定到模型 bindingContext.Result = ModelBindingResult.Success(sanitizedValue); return Task.CompletedTask; } }
2. 在模型属性上使用特性
直接在需要自动清理HTML的属性上标记[HtmlSanitize]即可,模型绑定过程中会自动处理:
public class ArticleModel { public string Title { get; set; } // 自动清理HTML内容 [HtmlSanitize] public string Content { get; set; } // 自定义允许的标签示例 [HtmlSanitize(AllowedTags = new[] { "p", "b", "i", "br" })] public string CustomHtmlContent { get; set; } }
3. 性能优化建议
- 将
HtmlSanitizer实例改为单例,避免每次绑定都创建新实例:
然后在特性的public static class SanitizerHelper { public static readonly HtmlSanitizer DefaultSanitizer = new HtmlSanitizer(); }BindModelAsync方法中替换为var sanitizer = SanitizerHelper.DefaultSanitizer;(如果使用自定义规则,则按需创建或复用对应配置的实例)
内容的提问来源于stack exchange,提问作者thran
相关产品推荐
相关产品推荐

