I use in some models a sub model class (UserInfo) which should contain some user related info. This sub model can be used in various models, For example
public class Model
{
int string Value { get; set; }
public UserInfo User { get; set; }
}
I've created a model binder and registered it in WebApiConfig
config.BindParameter(typeof(UserInfo), new UserModelBinder());
The thing is the UserModelBinder isn't called by the WebApi processing pipeline. It seems that these modelbinders aren't called for the sub models. Am I missing something ?
A model is an object that represents the data in your application. ASP.NET Web API can automatically serialize your model to JSON, XML, or some other format, and then write the serialized data into the body of the HTTP response message.
Answers. You can serialize the model into a json string and transfer it, and then deserialize the json string in the get method of WebAPI to get the model.
Using [FromBody] When a parameter has [FromBody], Web API uses the Content-Type header to select a formatter. In this example, the content type is "application/json" and the request body is a raw JSON string (not a JSON object).
In the MVC pattern, Model binding maps the HTTP request data to the parameters of a Controllers action method. The parameter can be of a simple type like integers, strings, double etc. or they may be complex types. MVC then binds the request data to the action parameter by using the parameter name.
Take a look at this question What is the equivalent of MVC's DefaultModelBinder in ASP.net Web API? for some detail on where your bindings are going to be happening.
I suspect though that your Model
is being passed in the message body?
If it is then WebApi will use a formatter to deserialise your types and process the model, the defaults being XmlMediaTypeFormatter
, JsonMediaTypeFormatter
or FormUrlEncodedMediaTypeFormatter
.
If you are posting the model in the body then depending on your requested or accepted content-type is (application/xml, application/json etc) you may need to customise the serialiser settings or wrap or implement your own MediaTypeFormatter
.
If you are using application/json then you can use JsonConverters
to customise the serialisation of your UserInfo class. There is an example of this here Web API ModelBinders - how to bind one property of your object differently and here WebApi Json.NET custom date handling
internal class UserInfoConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return objectType == typeOf(UserInfo);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue,
JsonSerializer serializer)
{
//
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//
}
}
HttpConfigurationExtensions.BindParameter method register that the given parameter type on an Action is to be bound using the model binder.
so what you did is similar to:
void Action([ModelBinder(UserModelBinder)] UserInfo info)
It works only if action parameter is of specified type (UserInfo).
Try putting model binder declaration on UserInfo class itself, so that it's global:
[ModelBinder(UserModelBinder)] public class UserInfo { }
However, there are some differences in the way how WebAPI and MVC bind parameters. Here is Mike Stall's detailed explanation.
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