I have a WebApi method, like this one:
public string Get([FromUri] SampleInput input)
{
    //do stuff with the input...
    return "ok";
}
The input is defined like this:
public class SampleInput
{
    // ...other fields
    public bool IsAwesome { get; set; }
}
As it is, it works OK: if I pass &isAwesome=true in the query string, the parameter is initializes with the value true.
My problem is that I'd like to accept both  &isAwesome=true and &isAwesome=1 as true values. Currently, the second version will result in IsAwesome being false in the input model.
What I tried, after reading the various blog posts on the subject, was to define an HttpParameterBinding:
public class BooleanNumericParameterBinding : HttpParameterBinding
{
    private static readonly HashSet<string> TrueValues =
        new HashSet<string>(new[] { "true", "1" }, StringComparer.InvariantCultureIgnoreCase);
    public BooleanNumericParameterBinding(HttpParameterDescriptor descriptor) : base(descriptor)
    {
    }
    public override Task ExecuteBindingAsync(
        ModelMetadataProvider metadataProvider, 
        HttpActionContext actionContext,
        CancellationToken cancellationToken)
    {
        var routeValues = actionContext.ControllerContext.RouteData.Values;
        var value = (routeValues[Descriptor.ParameterName] ?? 0).ToString();
        return Task.FromResult(TrueValues.Contains(value));
    }
}
... and register it in Global.asax.cs, using:
var pb = GlobalConfiguration.Configuration.ParameterBindingRules;
pb.Add(typeof(bool), p => new BooleanNumericParameterBinding(p));
and
var pb = GlobalConfiguration.Configuration.ParameterBindingRules;
pb.Insert(0, typeof(bool), p => new BooleanNumericParameterBinding(p));
None of these worked. My custom HttpParameterBinding is not being called and I still get the value 1 translated to false.
How can I configure WebAPI to accept the value 1 as true for Booleans?
Edit: The example I presented is intentionally simplified. I have a lot of input models in my application and they contain many boolean fields that I would like to be handled in the manner described above. If there was just this one field, I would not have resorted to such complex mechanisms.
Looks like decorating the parameter with the FromUriAttribute just skips the parameter binding rules altogether. I made a simple test replacing the SampleInput input parameter with a simple bool:
public string Get([FromUri] bool IsAwesome)
{
    //do stuff with the input...
    return "ok";
}
and the boolean rule is still not getting called (IsAwesome is coming as null when you call &isAwesome=1).
As soon as you remove the FromUri attribute:
public string Get(bool IsAwesome)
{
    //do stuff with the input...
    return "ok";
}
the rule gets called and the parameter correctly bound. The FromUriAttribute class is sealed, so I think you're pretty much screwed - well, you can always reimplement it and include your alternate boolean binding logic ^_^.
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