我正在尝试将用户输入的 HTML 字符串从 POST 绑定到模型对象上的简单字符串变量中。如果我使用该[AllowHtml]
属性,这可以正常工作。但是,我想在 HTML 进入模型之前对其进行清理,所以我创建了一个 ModelBinder:
public class SafeHtmlModelBinder : DefaultModelBinder
{
public override object BindModel(ControllerContext controllerCtx, ModelBindingContext bindingCtx)
{
var bound = base.BindModel(controllerCtx, bindingCtx);
// TODO - return a safe HTML fragment string
return bound;
}
}
还有一个CustomModelBinderAttribute
:
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = false)]
public class SafeHtmlModelBinderAttribute : CustomModelBinderAttribute
{
public SafeHtmlModelBinderAttribute()
{
binder = new SafeHtmlModelBinder();
}
private IModelBinder binder;
public override IModelBinder GetBinder()
{
return binder;
}
}
然后,我用新属性注释要清理的模型属性:
[Required(AllowEmptyStrings = false, ErrorMessage = "You must fill in your profile summary")]
[AllowHtml, SafeHtmlModelBinder, WordCount(Min = 1, Max = 300)]
public string Summary { get; set; }
这遵循http://msdn.microsoft.com/en-us/magazine/hh781022.aspx上的示例。不幸的是,它似乎不起作用!如果我在我的BindModel
方法中放置一个断点,它永远不会被命中。有任何想法吗?
更新
根据来自 Joel 的信息,我更改了 IModelBinder 以在SetProperty
方法中截取值,而是将其应用于SafeHtmlModelBinderAttribute
包含可以包含 HTML 的字符串属性的类。该代码检查该属性是一个字符串,并且在尝试清理之前还允许包含 HTML:
public class SafeHtmlModelBinder : DefaultModelBinder
{
protected override void SetProperty(
ControllerContext controllerCtx,
ModelBindingContext bindingCtx,
PropertyDescriptor property,
object value)
{
var propertyIsString = property.PropertyType == typeof(string);
var propertyAllowsHtml = property.Attributes.OfType<AllowHtmlAttribute>().Count() >= 1;
var input = value as string;
if (propertyIsString && propertyAllowsHtml && input != null)
{
// TODO - sanitize HTML
value = input;
}
base.SetProperty(controllerCtx, bindingCtx, property, value);
}
}