In my custom model binder I use
bindingContext.ValueProvider.GetValue(propertyName);
I do have [ValidateInput(false)] on the action. However the GetValue call above results in
A potentially dangerous Request.QueryString value was detected from the client
How do I make my custom model binder get the unvalidated value from the value provider? Of course when it finds that there's ValidateInput(false) on the action.
Just in case someone is curious, here's a quick solution. Just call CheckUnvalidated() in BindModel/BindProperty methods. This will replace default QueryStringValueProvider with the unvalidated version.
MethodInfo GetActionMethod(ControllerContext controllerContext)
{
var action = controllerContext.RouteData.Values["action"] as string;
return controllerContext.Controller.GetType().GetMethods().FirstOrDefault(x => x.Name == action ||
x.GetCustomAttribute<ActionNameAttribute>().SafeGet(a => a.Name) == action);
}
void CheckUnvalidated(ControllerContext controllerContext, ModelBindingContext bindingContext)
{
var method = GetActionMethod(controllerContext);
if (method == null)
return;
if (method.GetCustomAttribute<ValidateInputAttribute>().SafeGet(x => x.EnableValidation, true))
return;
var collection = bindingContext.ValueProvider as ValueProviderCollection;
if (collection == null)
return;
var old = collection.OfType<QueryStringValueProvider>().FirstOrDefault();
if (old != null)
collection.Remove(old);
collection.Add(new UnvalidatedQueryStringValueProvider(controllerContext));
}
class UnvalidatedQueryStringValueProvider : NameValueCollectionValueProvider
{
public UnvalidatedQueryStringValueProvider(ControllerContext controllerContext)
: base(controllerContext.HttpContext.Request.Unvalidated().QueryString, CultureInfo.InvariantCulture)
{
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With