Reputation: 40566
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.
Upvotes: 10
Views: 5880
Reputation: 151
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 ^_^.
Upvotes: 5