Reputation: 1500
This is, initially at least, more of an exploratory question to see what is and isn't possible and to see if what I would like to achieve is even possible.
At the moment I am using jQuery Unobtrusive validation in conjunction with MVCs standard server side validation to carry out validation before the data is submitted via a web form. Now, I want to have the form be a little more 'dynamic' so depending on the choice of a dropdown/radiobutton/checkbox etc. parts of the form will show or hide themselves, but this is present 2 issues to me:
jQuery Unobtrusive will still attempt to validate all form fields even if they are hidden or have their display set to none. I think I can get around this using some jQuery, a custom class tag on each element and then when the UI is updated, loop through the elements and remove/add the data-val
. This isn't the major issue
if(ModelState.IsValid())
check is going to fail, but I need the annotations there to trigger the client side validationI'm wondering, is there a way I can override the existing MVC server side validation logic so that if a certain checkbox or dropdown value has been selected, then some logic will simply be bypassed. I've written a very basic custom validation attribute before when I was wanting to limit access based on the connecting parties IP address.
I know I could make use of multiple ViewModels, but when the user first visits the site, the form won't know what type of submission they will be making until they choose the appropriate option, by that point a generic submission object will have already been passed to the View on the HTTP GET
controller method and ideally, I'd like to avoid any reloading of the page once a submission has been made to simply load a secondary ViewModel. I'm also making use of a file uploader and file information and so on is all stored within the ViewModel so this would also need to be passed around which I could see getting messy.
public class Submission
{
[HiddenInput(DisplayValue = false)]
public Guid SubmissionID { get; set; }
[Required(ErrorMessage = "Please provide your name")]
public string Name { get; set; }
[EmailAddress(ErrorMessage = "Invalid email address")]
[Required(ErrorMessage = "Please enter an email address")]
public string Email { get; set; }
[Required(ErrorMessage = "Please provide a contact number")]
[StringLength(13, ErrorMessage = "Phone number can be no more than 13 digits long")]
public string Phone { get; set; }
public string SubmissionPurpose { get; set; }
//Suspicious Transaction
//This should only be validated if, on the POST, the SubmissionPurpose matches the appropriate value
[Required(ErrorMessage = "Please provide a date")]
public string TransDateNoticed { get; set; }
public string TransAdditionalDetails { get; set; }
//Support Query
//This should only be validated if, on the POST, the SubmissionPurpose matches the appropriate value
[Required(ErrorMessage = "Please provide a date")]
public string SupDateNoticed { get; set; }
public string SupAdditionalDetails { get; set; }
//Additional Data
public string Message { get; set; }
public List<UploadedFile> Attachments { get; set; }
public IEnumerable<SelectListItem> SubmissionPurposes()
{
return new List<SelectListItem>
{
new SelectListItem() {Value = "", Text = "Please select an option"},
new SelectListItem() {Value = "Suspicious Transaction Reporting", Text = "Suspicious Transaction Reporting"},
new SelectListItem() {Value = "Request a Support Session", Text = "Request a Support Session"}
};
}
I'm pretty open to any and all suggestions, I'm thinking some sort of custom data annotation is the best way to go since that seems to be the only way I could have granular control over it, but then my question would be how to have an annotation like the idea I'm currently trying to work towards below
[CustomRequirement, SumissionPurpose = "Suspicious Transaction Reporting"]
I know in MVC 5.1 they introduced a new DropdownForEnum feature but from my looking so far I can't see anything new in 5.1 or 5.2 that might allow me to meet this need either.
Upvotes: 1
Views: 1255
Reputation: 644
Custom validation attributes are the way to go. Please note that if the properties in the model are complex objects and their validations depend on the parent object properties you will not get the validation context of the parent object property. In that case you have to think of writing your own model validators implementing from ModelValidator class and adding it to ModelValidatorProvider factory class.
Upvotes: 0
Reputation: 3055
I've used Foolproof Validation in the past. They provide several extra attributes and the clientside validation.
[Is]
[EqualTo]
[NotEqualTo]
[GreaterThan]
[LessThan]
[GreaterThanOrEqualTo]
[LessThanOrEqualTo]
[RequiredIf]
[RequiredIfNot]
[RequiredIfTrue]
[RequiredIfFalse]
[RequiredIfEmpty]
[RequiredIfNotEmpty]
[RequiredIfRegExMatch]
[RequiredIfNotRegExMatch]
Upvotes: 1