I've been trying to experiment with model binding to make our API easier to use. When using the API I can't get the model binding to bind when the data is in the body, only when it is part of the query.
The code I have is:
public class FunkyModelBinder : IModelBinder
{
public bool BindModel(HttpActionContext actionContext, ModelBindingContext bindingContext)
{
var model = (Funky) bindingContext.Model ?? new Funky();
var hasPrefix = bindingContext.ValueProvider
.ContainsPrefix(bindingContext.ModelName);
var searchPrefix = (hasPrefix) ? bindingContext.ModelName + "." : "";
model.Funk = GetValue(bindingContext, searchPrefix, "Funk");
bindingContext.Model = model;
return true;
}
private string GetValue(ModelBindingContext context, string prefix, string key)
{
var result = context.ValueProvider.GetValue(prefix + key);
return result == null ? null : result.AttemptedValue;
}
}
When looking at the ValueProvider
property on the bindingContext
I only see QueryStringValueProvider
and RouteDataValueProvider
which I think means that if the data is in the body I won't get it. How should I do this? I would like to support posting data as either json or form-encoded.
I am looking into this as well.
WebApis Model Binder comes with two built in ValueProviders.
QueryStringValueProviderFactory & RouteDataValueProviderFactory
Which are searched when you call
context.ValueProvider.GetValue
This question has some code on how to bind data from the body.
how to pass the result model object out of System.Web.Http.ModelBinding.IModelBinder. BindModel?
You could create a custom ValueProvider to do this as well, probably a better idea - which will be searched for the value matching the key. The above link just does this within the model binder, which limits the ModelBinder to looking only in the body.
public class FormBodyValueProvider : IValueProvider
{
private string body;
public FormBodyValueProvider ( HttpActionContext actionContext )
{
if ( actionContext == null ) {
throw new ArgumentNullException( "actionContext" );
}
//List out all Form Body Values
body = actionContext.Request.Content.ReadAsStringAsync().Result;
}
// Implement Interface and use code to read the body
// and find your Value matching your Key
}
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