queen3
queen3

Reputation: 15511

Unvalidated IValueProvider.GetValue

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.

Upvotes: 7

Views: 825

Answers (1)

queen3
queen3

Reputation: 15511

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)
     {
         }
  }

Upvotes: 1

Related Questions