Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional [Required] on complex types

I'm trying to get my viewmodel set up for a form that will collect information about people joining a team. The form must contain some leadup information, then a list of 5 "Team Members" (each containing a name, email, and phone), the first two of which will be required. For my validation I would like it to be on the individual fields, like this:

Person 1:
Name: (validation messaage)
Email: (validation message)
Phone: (validation message)

Person 2:
Name: (validation messaage)
Email: (validation message)
Phone: (validation message)

Person 3:
Name: 
Email:
Phone:

Person 4:
Name: 
Email:
Phone:

Person 5:
Name: 
Email: 
Phone: 

The relevant portion of my viewmodel is currently:

[Required]
public TeamMember TeamMember1 { get; set; }

[Required]
public TeamMember TeamMember2 { get; set; }

public TeamMember TeamMember3 { get; set; }

public TeamMember TeamMember4 { get; set; }

public TeamMember TeamMember5 { get; set; }

so in my view, I just write:

@Html.EditorFor(model=>model.TeamMember1)

@Html.EditorFor(model=>model.TeamMember2)

@Html.EditorFor(model=>model.TeamMember3)

@Html.EditorFor(model=>model.TeamMember4)

@Html.EditorFor(model=>model.TeamMember5)

the editor template looks like this:

@model MyProject.Models.TeamMember

<div class="editor-label">
    @Html.LabelFor(model => model.Name)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Name)
    @Html.ValidationMessageFor(model => model.Name)
</div>

<div class="editor-label">
    @Html.LabelFor(model => model.Email)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Email)
    @Html.ValidationMessageFor(model => model.Email)
</div>

<div class="editor-label">
    @Html.LabelFor(model => model.Phone)
</div>
<div class="editor-field">
    @Html.EditorFor(model => model.Phone)
    @Html.ValidationMessageFor(model => model.Phone)
</div>

Sorry for throwing so much into one thread, but does anyone have a suggestion as to how best to set this up? I've thought about inheriting from RequiredAttribute and replacing [Required] on the TeamMember properties, but I'm not sure how to set the validation messages on the child fields. Right now, even if it's empty it passes the required check, I'm assuming because the objects are bound (and so not null) even though all of the properties are blank.

Any feedback is appreciated.

like image 713
Aaron Avatar asked Nov 13 '22 11:11

Aaron


1 Answers

You can write a custom validator. Below is an example of how you can access the values of other properties. You can then either decorate TeamMember or the property with this custom validation attribute depending on the validation logic. I would recommend it at the class level

protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
    //Retreive value of Name property
    var nameProperty = validationContext.ObjectType.GetProperty("Name");
    var namePropertyValue = (string)nameProperty.GetValue(validationContext.ObjectInstance, null);

    var propertyBeingValidatedValue = (string)value;

    //Validation logic
    if ((!string.IsNullOrEmpty(propertyBeingValidatedValue)) && (!string.IsNullOrEmpty(namePropertyValue)))
    {
        //returning null means everything is good.
        return null;
    }
    //return a message in any other case.
    return new ValidationResult("Validation Message");
}
like image 111
Anil Ali Avatar answered Dec 17 '22 12:12

Anil Ali