Mam dwa ViewModels (uproszczony):Walidacja zagnieżdżonych ViewModels
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, }
}
a następna akcja kontroler postu:
[HttpPost]
public ActionResult Create(ParentViewModel viewModel)
{
if (ModelState.IsValid)
{
// process viewModel -> write something into database
return RedirectToAction("Index");
}
return View(viewModel);
}
Teraz przesyłam następujące wartości formularza w ciele żądania POST do URL odpowiadające tej skargi (ręcznie w Fiddler żądanie Builder):
Content.Name1 = X
Działa to dobrze, właściwość
Name1
jest wypełnioneviewModel.Content
,Name2
jestnull
a państwo model jest nieważne, ponieważName2
jest wymagane. Tak więc sprawdzanie poprawności nie powiedzie się zgodnie z oczekiwaniami.Xontent.Name1 = X lub Nazwa1 = X lub cokolwiek, tak że nic nie zostanie związana z
viewModel
Teraz
viewModel.Content
nie jestnull
(bo mam instancji go w konstruktorze), ale wszystko właściwościName1
iName2
sąnull
. To jest oczekiwane. Co zrobiłem nie oczekiwać, że stan modelu jest ważne, więc przechodzi walidacji (prowadząc do wyjątków DB później, ponieważ istnieją nie-zerowalne kolumn).
Jak mogę poprawić ten kod tak, że walidacja działa również w drugim przypadku?
I tak trzech doświadczeniach
I Usunięto instancji z
Content
w konstruktoraParentViewModel
, następnieContent
jestnull
w drugim przykładzie powyżej, ale nadal przechodzi walidacji.Dodałem atrybut do właściwości
Content
[Required]
(ale nie usunąć konkretyzacjiContent
w konstruktorzeParentViewModel
). Nie ma to żadnego efektu, opisane zachowanie obu powyższych testów jest takie samo.I dodano atrybut
[Required]
do właściwościContent
i usunęła instancji zContent
w konstruktoraParentViewModel
. Wydaje się, że działa tak, jak chcę: W drugim teścieContent
jestnull
i sprawdzanie poprawności nie powiedzie się z powodu atrybutu[Required]
.to będzie wyglądać następująco:public class ParentViewModel { [Required] public ChildViewModel Content { get; set, } } public class ChildViewModel { [Required] public string Name1 { get; set, } [Required] public string Name2 { get; set, } }
chciałbym stwierdzić, że teraz instancji właściwość Content
dzieci w konstruktorze ParentViewModel
jest źródłem problemu i że sama spoiwo model musi instancji właściwości podrzędne (lub nie , jeśli nie ma pasujących pól formularza w żądaniu), aby mieć poprawnie działającą walidację po stronie serwera.
Mam instancję podrzędną właściwości w kilku innych konstruktorach modeli widoku i nie zauważyłem tego problemu do tej pory. Czy na ogół jest to zła praktyka? Czy istnieją inne sposoby rozwiązania problemu?
Obecnie walczę z czymś podobnym. Jedyną różnicą w moim przypadku jest, że mam 'IEnountable' of ChildViewModels. Wypróbowałem wszystkie trzy powyższe opcje i żaden nie działa dla mnie. –