Sto tentando di associare una stringa HTML immessa dall'utente da un POST a una variabile stringa semplice su un oggetto modello. Funziona bene se utilizzo l'attributo [AllowHtml]
. Tuttavia, mi piacerebbe sanificare l'HTML prima si fa strada nel modello così ho creato un ModelBinder:Utilizzo di un Raccoglitore modello personalizzato per stringhe HTML
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;
}
}
E anche un 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;
}
}
Ho quindi annotare le proprietà modello che voglio essere sterilizzate con il nuovo attributo:
[Required(AllowEmptyStrings = false, ErrorMessage = "You must fill in your profile summary")]
[AllowHtml, SafeHtmlModelBinder, WordCount(Min = 1, Max = 300)]
public string Summary { get; set; }
Questo sta seguendo l'esempio a http://msdn.microsoft.com/en-us/magazine/hh781022.aspx. Sfortunatamente, non sembra funzionare! Se metto un breakpoint nel mio metodo BindModel
non viene mai colpito. Qualche idea?
UPDATE
Sulla base delle informazioni da Joel ho cambiato IModelBinder di intercettare il valore quando nel metodo SetProperty
e applicare invece la SafeHtmlModelBinderAttribute
alle proprietà della classe String contenente che possono contenere HTML. Il codice di verifica che la proprietà è una stringa e è anche permesso di contenere HTML prima di provare a disinfettare:
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);
}
}
Do CustomModelBinderAttribute funziona sulle proprietà?Osservando il codice sorgente MVC, questo attributo viene utilizzato solo su 'internal const AttributeTargets ValidTargets = AttributeTargets.Class | AttributeTargets.Enum | AttributeTargets.Interface | AttributeTargets.Parameter | AttributeTargets.Struct; '... che mi suggerisce che il framework non può aspettarsi di vederlo sulle proprietà. – Schneider