开发者

Default Model Binder does not bind for Nullable types in IEnumerable

开发者 https://www.devze.com 2023-03-01 21:02 出处:网络
I have a controller action whose definition looks like- public ActionResult ChangeModel( IEnumerable<MyModel> info, long? destinationId)

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开发者_如何学JAVA 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.

0

精彩评论

暂无评论...
验证码 换一张
取 消