У меня есть две модели представления (упрощенно):
public class ParentViewModel
{
public ParentViewModel
{
Content = new ChildViewModel();
}
public ChildViewModel Content { get; set, }
}
public class ChildViewModel
{
[Required]
public string Name1 { get; set, }
[Required]
public string Name2 { get; set, }
}
И следующее действие контроллера для публикации:
[HttpPost]
public ActionResult Create(ParentViewModel viewModel)
{
if (ModelState.IsValid)
{
// process viewModel -> write something into database
return RedirectToAction("Index");
}
return View(viewModel);
}
Теперь я отправляю следующие значения формы в теле запроса на отправкуURL, соответствующий этому действию (вручную в Fiddler Request Builder):
Content.Name1 = X
Это прекрасно работает, Name1
свойство заполнено viewModel.Content
, Name2
равно null
, а состояние модели недопустимо, так как требуется Name2
.Таким образом, проверка завершается неудачно, как и ожидалось.
Xontent.Name1 = X или Name1 = X или что угодно, чтобы ничто не связывалось с viewModel
Теперь viewModel.Content
- это не null
(потому что я создаю его экземпляр в конструкторе), но все свойства Name1
и Name2
равны null
.Это ожидается.Я не ожидал, что состояние модели будет допустимо , поэтому оно проходит проверку (что приводит к исключениям из БД позже, поскольку имеются столбцы, не допускающие значения NULL).
Как улучшить этот код, чтобы проверка работала и во втором случае?
Я провел три эксперимента:
Я удалилсоздание экземпляра Content
в конструкторе ParentViewModel
, тогда Content
равно null
во втором примере выше, но проверка все еще проходит.
Я добавил [Required]
Атрибут к свойству Content
(но не удалить экземпляр Content
в конструкторе ParentViewModel
).Это никак не влияет, описанное поведение двух тестов выше.
Я добавил атрибут [Required]
к свойству Content
и удалено создание экземпляра Content
в конструкторе ParentViewModel
.Кажется, это работает так, как я хочу: во втором тесте Content
равен null
, и проверка не проходит из-за атрибута [Required]
.Это выглядело бы так:
public class ParentViewModel
{
[Required]
public ChildViewModel Content { get; set, }
}
public class ChildViewModel
{
[Required]
public string Name1 { get; set, }
[Required]
public string Name2 { get; set, }
}
Теперь я пришел бы к выводу, что создание экземпляра дочернего свойства Content
в конструкторе ParentViewModel
является источником проблемы и связывателем моделиСам должен создавать экземпляры дочерних свойств (или нет, если в запросе нет соответствующих полей формы), чтобы иметь правильно работающую проверку на стороне сервера.
У меня есть создание экземпляров дочерних свойств в нескольких других конструкторах модели представления ине замечал этой проблемы до сих пор.Так это вообще плохая практика?Есть ли другие способы решения проблемы?