Модель Binder по умолчанию не привязывается для типов Nullable в IEnumerable

У меня есть действие контроллера, определение которого выглядит как

public ActionResult ChangeModel( IEnumerable<MyModel> info, long? destinationId)

И модель:

public class MyModel
{
    public string Name; //Gets populated by default binder
    public long? SourceId; //remains null though the value is set when invoked
}

Свойство "Имя" заносится в действие контроллера, однако свойство SourceId остается пустым. destinationId, который является параметром long?, также заселяется.

При переходе через исходный код MVC (версия 2) это исключение, вызванное DefaultModelBinder.

Преобразование параметров из типа 'System.Int32' для ввода типа 'System.Nullable`1 [[System.Int64, mscorlib, Version = 2.0.0.0, Culture = neutral, PublicKeyToken = b77a5c561934e089]]' не удалось, поскольку преобразователь типа не может преобразовывать между этими типами.

Если модель изменена на длинную, а не длинную?, связующее устройство по умолчанию устанавливает значение.

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
}

Это известная проблема? Поскольку исходный код MVC оптимизирован, я не могу выполнить большую часть кода.

Обновление: отправленный запрос является Http POST с использованием Json с похожим исходным JSon -

{"info":[{"Name":"CL1","SourceId":2}], "destinationId":"1"}

Ответы

Ответ 1

Возможно, это слишком поздно, но я нашел обходное решение. Вы можете преобразовать исходное поле в строку перед отправкой данных. Таким образом, ваши данные JSON будут выглядеть как

{"info":[{"Name":"CL1","SourceId":"2"}], "destinationId":"1"}

Это сработало в моей ситуации (Int32 → decimal?, ASP NET MVC 3)

Ответ 2

Я бы рекомендовал вам использовать свойства вместо полей в вашей модели просмотра:

public class MyModel
{
    public string Name { get; set; }
    public long? SourceId { get; set; }
}

Теперь следующий запрос:

/somecontroller/changemodel?destinationId=123&info[0].Name=name1&info[0].SourceId=1&info[1].Name=name2&info[1].SourceId=2

Заполняет модель.

Ответ 3

По умолчанию модель Binder анализирует все значения SourceId как int. Но, похоже,.NET отсутствует преобразователь типа по умолчанию от int до long?.

Что бы я сделал, реализовать конвертер типов для этого случая.