Reputation: 3455
I'm using ASP.NET-MVC Core 2.1 and I have this ViewModel
class in my code
public class HomeViewModel
{
public HomeViewModel()
{
Section1 = new HomeSection1ViewModel();
Section2 = new HomeSection2ViewModel();
}
public HomeSection1ViewModel Section1 { get; set; }
public HomeSection2ViewModel Section2 { get; set; }
}
public class HomeSection1ViewModel
{
public Guid ID { get; set; }
[Required(ErrorMessage = "Required")]
public string Title { get; set; }
[Required(ErrorMessage = "Required")]
public string Description { get; set; }
[Required(ErrorMessage = "Required")]
public string Link { get; set; }
}
public class HomeSection2ViewModel
{
public HomeSection2ViewModel()
{
Details = new List<HomeSection2DetailViewModel>();
}
public Guid ID { get; set; }
[Required(ErrorMessage = "Required")]
public string Title { get; set; }
[Required(ErrorMessage = "Required")]
public string Header { get; set; }
public List<HomeSection2DetailViewModel> Details { get; set; }
}
public class HomeSection2DetailViewModel
{
public Guid ID { get; set; }
[Required(ErrorMessage = "Required")]
public string Title { get; set; }
public string Description { get; set; }
public string Link { get; set; }
[Required(ErrorMessage = "Required")]
[Range(0, int.MaxValue, ErrorMessage = "Please enter a valid number")]
public int? Sequence { get; set; }
public DatabaseAction Action { get; set; }
}
My view page will bind HomeViewModel
as its Model
, my question is how do I validate only certain part of the Model
? For example I want to validate Section2
but not Section1
in my Controller. How do I achieve that?
Any response will be appreciated.
Upvotes: 3
Views: 2749
Reputation:
Your HomeViewModel
has a constructor which initializes both the HomeSection1ViewModel
and HomeSection2ViewModel
properties. The DefaultModelBinder
initializes an instance of HomeViewModel
in the POST method and calls its constructor which means that both Section1
and Section2
properties are initialized, but because you are only posing values for only one, the other will be invalid because of the validation attributes applied to its properties.
Remove the constructor from HomeViewModel
so that only Section2
is initialized by the DefaultModelBinder
(based on values from the request). Section1
will be null
by default, therefore no validation is performed on any of its properties.
Upvotes: 1
Reputation: 1487
Looks like you will be binding your HomeViewModel to different Views and in some Views you want to validate some properties as mentioned.
There are multiple approaches to get this done, here are 2 I can think of:
1- Implement IValidatableObject in your ViewModel
public class HomeSection2ViewModel : : IValidatableObject
{
public HomeSection2ViewModel()
{
Details = new List<HomeSection2DetailViewModel>();
}
public Guid ID { get; set; }
public string Title { get; set; }
public string Header { get; set; }
public bool Validate { get; set; }
public List<HomeSection2DetailViewModel> Details { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(Validate)
{
if(string.IsNullOrEmpty(Title)
{
yield return
new ValidationResult(errorMessage: "required",
memberNames: new[] { "Title" });
}
}
}
}
2- Or Bind each View to a version of the ViewModel with the required validation and use AutoMapper to map the Model to the ViewModel or the ViewModel to another ViewModel.
Upvotes: 0
Reputation: 11
This could be achieved by client-side authentication and not server-side.
Else you could override your model.
public class BaseModel
{
[Required]
public string RequiredProperty { get; set; }
}
public class DerivativeModel : BaseModel
{
new public string RequiredProperty { get; set; }
}
Enjoy;)
Upvotes: 0