Say I have a controller like:
public class MyController : ApiController {
[Route("{myarg}")]
[HttpGet]
public async Task<Foo> Get(string myarg)
{
return await ...
}
}
The myarg
argument needs to be 'normalized'. Let's say I always want to trim it, uppercase it and string-reverse it. The actual operations don't matter, they're just an example so I'm not looking for methods to trim or reverse a string.
I have a bunch of controllers with all a bunch of methods with all similar arguments. I'd like to have a way to annotate those methods or do something else to make sure the arguments are always 'normalized' before they are even passed into the method. I have looked into route constraints (custom route constraints in particular) but that doesn't provide a method to do what I want (which makes sense since it's not a real constraint).
Ideally I'd like to annotate the method with an attribute like:
[MyNormalize("{myarg}")]
Or something in a similar fashion like the RouteAttribute
s. What would be the best way to go about this and implement this in a clean fashion?
[FromQuery] - Gets values from the query string. [FromRoute] - Gets values from route data. [FromForm] - Gets values from posted form fields. [FromBody] - Gets values from the request body.
The [FromUri] attribute is prefixed to the parameter to specify that the value should be read from the URI of the request, and the [FromBody] attribute is used to specify that the value should be read from the body of the request.
A Get does not send the body of the form, it only requests a URL. Use a <form> in your view and post it to your controller method, which needs to be decorated with HttpPost.
It's worth noting that ideally, you'll only want to tweak model-binding in order to correctly bind the passed value, not transforming it.
Anyway, here's the custom model-binder:
public class MyArgModelBinder : System.Web.Http.ModelBinding.IModelBinder
{
public bool BindModel(HttpActionContext actionContext, System.Web.Http.ModelBinding.ModelBindingContext bindingContext)
{
var val = bindingContext.ValueProvider.GetValue(bindingContext.ModelName);
// transform to upper-case
var transformedValue = val.AttemptedValue.ToUpperInvariant();
bindingContext.Model = transformedValue;
return true;
}
}
Then apply it:
[Route("{myarg}")]
[HttpGet]
public async Task<Foo> Get([ModelBinder(typeof(MyArgModelBinder))] string myarg)
{
// at this point, `myarg` would contain the transformed value
...
}
See Documentation
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