Search code examples
asp.net-mvcasp.net-web-apidata-bindingmodel-validation

OnActionExecuting actionContext binding bool parameter turned string


I have an ActionFilterAttribute where I expect a ViewModel with one of its paramaters as a string.

I read it in the "OnActionExecuting(HttpActionContext actionContext)" method.

As a test, I am sending this parameter as a boolean value: true (instead of a string and without quotes), but the framework is automatically transforming this true boolean into "true" as a string.

Is there a way I can validate that this input parameter is a true or a "true"?


Solution

  • So if I understand correctly I think what you actually want is a custom model binder.

    public class NoBooleanModelBinder : IModelBinder
    {
        public bool BindModel(
            HttpActionContext actionContext,
            ModelBindingContext bindingContext)
        {
            if (bindingContext.ModelType != typeof(string))
            {
                return false; //we only want this to handle string models
            }
    
            //get the value that was parsed
            string modelValue = bindingContext.ValueProvider
                .GetValue(bindingContext.ModelName)
                .AttemptedValue;
    
            //check if that value was "true" or "false", ignoring case.
            if (modelValue.Equals(bool.TrueString, StringComparison.OrdinalIgnoreCase) ||
                modelValue.Equals(bool.FalseString, StringComparison.OrdinalIgnoreCase))
            {
                //add a model error.
                bindingContext.ModelState.AddModelError(bindingContext.ModelName,
                    "Values true/false are not accepted");
    
                //set the value that will be parsed to the controller to null
                bindingContext.Model = null;
            }
            else
            {
                //else everything was okay so set the value.
                bindingContext.Model = modelValue;
            }
    
            //returning true just means that our model binder did its job
            //so no need to try another model binder.
            return true;
        }
    }
    

    Then you might do something like this in your Controller:

    public object Post([ModelBinder(typeof(NoBooleanModelBinder))]string somevalue)
    {
        if(this.ModelState.IsValid) { ... }
    }