Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customers Truncating Querystring, causes FormatException

Tags:

c#

asp.net-mvc

Every so often at Rentler we see the error

System.FormatException, String was not recognized as a valid Boolean

in our health monitoring. As it turns out, it looks like our customers are occasionally truncating the end of the url when copy/pasting it elsewhere. It just so happens that a boolean parameter tends to be on the end of the string, and when a customer shares it over some social network we get dumped with error reports.

https://{domain}/search?sid=17403777&nid=651&location=840065&propertytypecode=1&photosonly=fals

We use model binding for everything, so I'm not really sure how to deal with this. I could change the property to a string and attempt to parse it in the controller action, but that's sloppy. Is there any simple, fluent way to get the model binder to TryParse() it and just resolve to false if it can't?

like image 440
Dusda Avatar asked Oct 15 '12 17:10

Dusda


1 Answers

how about custom model binder for boolean data type? you would need something like this:

/// <summary>
/// A custom model binder for boolean values. This behaves the same as the default
/// one, except it will resolve the value to false if it cannot be parsed.
/// </summary>
public class BooleanModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        ValueProviderResult valueResult = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);

        //MVC checkboxes need specific handling in checked state
        if (string.Equals(valueResult.AttemptedValue, "true,false"))
        {
            AddToModelState(bindingContext, valueResult);
            return true;
        }

        bool parsed = false;
        if (Boolean.TryParse(valueResult.AttemptedValue, out parsed))
        {
            AddToModelState(bindingContext, valueResult);
            return parsed;
        }

        return false;
    }

    private static void AddToModelState(ModelBindingContext bindingContext, ValueProviderResult valueResult)
    {
        bindingContext.ModelState.Add(bindingContext.ModelName, new ModelState { Value = valueResult });
    }
}

//in Global.asax
protected void Application_Start()
{
    ...
    ModelBinders.Binders.Add(typeof(bool), new BooleanModelBinder());
}
like image 76
pkmiec Avatar answered Oct 21 '22 05:10

pkmiec