Поведение DefaultModelBinder, когда свойство отсутствует в запросе - PullRequest
0 голосов
/ 02 августа 2011

У меня есть модель, подобная следующей:

public class TestViewModel
{
  string UpdateProperty { get; set; }
  string IgnoreProperty { get; set; }
  ComplexType ComplexProperty { get; set; }
}

, где

public class ComplexType
{
  long? Code { get; set; }
  string Name { get; set; }
}

Мое действие контроллера:

public Edit(int id, FormColleciton formCollection)
{
  var model = service.GetModel(id);
  TryUpdateModel(model);

  //...
}

При вызове действия Edit у меня есть параметр formCollection, содержащий только ключ / значение для UpdateProperty.

После того, как вызов TryUpdateModel UpdateProperty установлен правильно, IgnoreProperty остается без изменений, но для ComplexProperty устанавливается значение NULL, даже если ранее оно имело значение.

Должен ли TryUpdateModel () изменять только свойства, являющиеся частью запроса? Если это не так, каков наилучший способ обойти это, поэтому ComplexProperty изменяется только в том случае, если он включен в запрос?


После того, как Дарин указал, что приведенный выше тестовый пример не продемонстрировал проблему, я добавил сценарий, где эта проблема действительно возникает:

public class TestViewModel
{
    public List<SubModel> List { get; set; }
}

public class SubModel
{
    public ComplexType ComplexTypeOne { get; set; }
    public string StringOne { get; set; }
}

public class ComplexType
{
    public long? Code { get; set; }
    public string Name { get; set; }
}

Действие контроллера:

public ActionResult Index()
{
    var model = new TestViewModel
                    {
                        List = new List<SubModel> { 
                            new SubModel{
                                ComplexTypeOne = new ComplexType{Code = 1, Name = "5"},
                                StringOne = "String One"
                            } 
                        }
                    }; 

    if (TryUpdateModel(model)) { } 

    return View(model);
}

Отправка запроса:

/Home/Index?List[0].StringOne=test

обновляет свойство SubModel.StringOne, но устанавливает для ComplexTypeOne значение null, даже если оно не включено в запрос.

Является ли это ожидаемым поведением (учитывая, что это не происходит, если не используется перечисление сложных типов)? Как лучше обойти это?

1 Ответ

1 голос
/ 02 августа 2011

В вашем тестовом примере должно быть что-то не так, поскольку я не смог его воспроизвести.Вот что я попробовал:

Модель (обратите внимание, что я использую общедоступные свойства):

public class TestViewModel
{
    public string UpdateProperty { get; set; }
    public string IgnoreProperty { get; set; }
    public ComplexType ComplexProperty { get; set; }
}

public class ComplexType
{
    public long? Code { get; set; }
    public string Name { get; set; }
}

Контроллер:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new TestViewModel
        {
            IgnoreProperty = "to be ignored",
            UpdateProperty = "to be updated",
            ComplexProperty = new ComplexType
            {
                Code = 1,
                Name = "5"  
            }
        };

        if (TryUpdateModel(model))
        {

        }
        return View();
    }
}

Теперь я отправляю следующий запрос: /home/index?UpdateProperty=abc и внутри условия только UpdateProperty изменяется с новым значением из строки запроса.Все остальные свойства, включая сложное свойство, остаются нетронутыми.

Также обратите внимание, что параметр действия FormCollection бесполезен.

...