使用HTML字符串的自定义模型绑定器

djb*_*djb 7 c# asp.net-mvc model-binding

我试图将用户输入的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我使用new属性注释我想要清理的模型属性:

[Required(AllowEmptyStrings = false, ErrorMessage = "You must fill in your profile summary")]
[AllowHtml, SafeHtmlModelBinder, WordCount(Min = 1, Max = 300)]
public string Summary { get; set; }
Run Code Online (Sandbox Code Playgroud)

这是在http://msdn.microsoft.com/en-us/magazine/hh781022.aspx上的示例.不幸的是,它似乎没有用!如果我在我的BindModel方法中放置断点,它永远不会被击中.有任何想法吗?

UPDATE

基于来自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);
    }
}
Run Code Online (Sandbox Code Playgroud)

Joe*_*ell 1

我一直在为同样的事情而苦苦挣扎。似乎从未调用过 GetBinder() 方法。经过深入研究后,我发现这篇文章中接受的答案是不可能为属性添加模型绑定属性。

我不知道这是否属实,但现在我只是尝试以不同的方式实现我需要做的事情。一种想法是创建一个更通用的 ModelBinder 并在执行绑定时检查属性是否存在,类似于此答案中建议的内容。