I have two ViewModels (simplified):
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, } }
And the following controller post-control action:
[HttpPost] public ActionResult Create(ParentViewModel viewModel) { if (ModelState.IsValid) {
Now I send the following form values ββto the body of the mail request to the URL corresponding to this action (manually in Fiddler Request Builder):
Content.Name1 = X
This works great, the Name1 property Name1 populated in viewModel.Content , Name2 is null , and the model state is invalid because Name2 is required. Therefore, the check is not performed as expected.
Xontent.Name1 = X or Name1 = X or whatever is associated with viewModel
Now viewModel.Content not null (because I instantiate it in the constructor), but all the properties of Name1 and Name2 are null . It is expected. What I did not expect is that the state of the model is valid, so it passes the test (leading to database exceptions later because there are columns with a non-empty value).
How can I improve this code so that validation also works in the second case?
I did three experiments:
I deleted the Content instance in the ParentViewModel constructor, then Content is null in the second example above, but validation is still ongoing.
I added the [Required] attribute to the Content property (but did not delete the Content instance in the ParentViewModel constructor). This has no effect, the described behavior of the two above tests is the same.
I added the [Required] attribute to the Content property and deleted the Content instance in the ParentViewModel constructor. This seems to work the way I want: in the second test, Content is null , and the validation fails due to the [Required] attribute. It will look like this:
public class ParentViewModel { [Required] public ChildViewModel Content { get; set, } } public class ChildViewModel { [Required] public string Name1 { get; set, } [Required] public string Name2 { get; set, } }
In conclusion, I would like to conclude that the creation of the parent Content property in the ParentViewModel constructor is the source of the problem and that the picker itself must create instances of the child properties (or not, if the request is in the field) in order to have the correct working check on the server side .
I have an instance of a child property in several constructors of other views and still have not noticed this problem. So, is this generally bad practice? Are there other ways to solve the problem?
Slauma
source share