locked
Way to implement DataAnnotation required conditionally RRS feed

  • Question

  • User-882770083 posted

    I came to this problem that if I have this property value then I need to make this another property as a required field.

    Is there a way to implement this on the Data Annotation ?

    Saturday, February 1, 2020 1:24 AM

All replies

  • User711641945 posted

    Hi xshiiiidev,

    You could custom ValidationAttribute like below:

    1.Model:

    public class Test
    {
    public int Id { get; set; } [RequieredIf("EmailAddress")] public int Age { get; set; } public string EmailAddress { get; set; } }

    2.RequiredIfAttribute:

    public class RequieredIfAttribute : ValidationAttribute
    {
        private readonly string _otherProperty;
    
        public RequieredIfAttribute(string otherProperty)
        {
            _otherProperty = otherProperty;
        }
    
        protected override ValidationResult IsValid(object value, ValidationContext validationContext)
        {
            var property = validationContext.ObjectType.GetProperty(_otherProperty);
            if (property == null)
            {
                return new ValidationResult(string.Format(
                    null,
                    "Unknown property {0}",
                    new[] { _otherProperty }
                ));
            }
            var otherPropertyValue = property.GetValue(validationContext.ObjectInstance, null);
    
            if (otherPropertyValue == null || otherPropertyValue as string == string.Empty)
            {
                var data = validationContext.DisplayName;
                if (value != null || value as string != string.Empty)
                {
                    return new ValidationResult(string.Format(
                        null,
                        "{0} is required if Age has value",
                        new[] { _otherProperty }
                    ));
                }
            }
    
            return null;
        }
    }

    3.View:

    @model Test
    
    <hr />
    <div class="row">
        <div class="col-md-4">
            <form asp-action="Create">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <div class="form-group">
                    <label asp-for="Age" class="control-label"></label>
                    <input asp-for="Age" class="form-control" />
                    <span asp-validation-for="Age" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <label asp-for="EmailAddress" class="control-label"></label>
                    <input asp-for="EmailAddress" class="form-control" />
                    <span asp-validation-for="EmailAddress" class="text-danger"></span>
                </div>
                <div class="form-group">
                    <input type="submit" value="Create" class="btn btn-primary" />
                </div>
            </form>
        </div>
    </div>
    
    <div>
        <a asp-action="Index">Back to List</a>
    </div>
    
    @section Scripts {
        @{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
    }

    4.Controller:

    public IActionResult Create()
    {
        return View();
    }
    
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> Create([Bind("Id,Age,EmailAddress")] Test tests)
    {
        if (ModelState.IsValid)
        {
            _context.Add(tests);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(tests);
    }

    Best Regards,

    Rena

    Monday, February 3, 2020 10:48 AM