I have a controller action whose definition looks like-
public ActionResult ChangeModel( IEnumerable<MyModel> info, long? destinationId)
And the model:
public class MyModel
{
public string Name; //Gets populated by default binder
public long? SourceId; //remains null though the value is set when invoked
}
The 'Name' property gets populated in the controller action however the SourceId property remains null. The destinationId which is a long? parameter gets populated as well.
While stepping through the MVC (version 2) source code this is the exception thrown by DefaultModelBinder.
The parameter conversion from type 'System.Int32' to type 'System.Nullable`1[[System.Int64, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]' failed because no type converter can convert between these types.
If the model is changed to long instead of long?, the default model binder sets the value.
public class MyModel
{
public string Name {get;set;}; //Gets populated by default binder
public long SourceId {get;set;}; //No longer long?, so value gets set
}
Is this a known issue? Since the MVC source code is optimized, I am not able to step through most of the code.
Update: The request being sent is a Http POST using Json with the source JSon resembling -
{"info":[{"Name":"CL1","SourceId":2}], "destinationId":"1"}
Model Binding is the most powerful mechanism in Web API 2. It enables the response to receive data as per requester choice. i.e. it may be from the URL either form of Query String or Route data OR even from Request Body. It's just the requester has to decorate the action method with [FromUri] and [FromBody] as desired.
Model binding is a simplistic way to correlate C# code with an HTTP request. The model binding applies to transforming the HTTP request data in the query's form string and form collection of the action method parameters. We can consider these parameters to be primitive type or complex type.
Model binding allows controller actions to work directly with model types (passed in as method arguments), rather than HTTP requests. Mapping between incoming request data and application models is handled by model binders.
Maybe it's too late, but I have found a workaround. You can convert the SourceId field to string before sending data. So your JSON data will look like
{"info":[{"Name":"CL1","SourceId":"2"}], "destinationId":"1"}
This worked in my situation (Int32 -> decimal?, ASP NET MVC 3)
I would recommend you to use properties instead of fields on your view model:
public class MyModel
{
public string Name { get; set; }
public long? SourceId { get; set; }
}
Now the following request:
/somecontroller/changemodel?destinationId=123&info[0].Name=name1&info[0].SourceId=1&info[1].Name=name2&info[1].SourceId=2
Populates the model fine.
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