简体   繁体   中英

Default Model Binder does not bind for Nullable types in IEnumerable

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"}

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.

The Default Model Binder is parsing all SourceId values as ints. But it seems .NET is missing a default type converter from int to long? .

What I would do is implementing a type converter for that case.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM