locked
Custom Model Validation (IValidatableObject) Not working... RRS feed

  • Question

  • User-121299044 posted

    Hello and thanks for reading.  I'm a newbie, trying to learn .net core.  I was learning how to create a custom validator, not using the Validation Attribute but at the class level. Unfortunately, I can't make this one work, please check my code below:  

    public class Blog : IValidatableObject
        {
            public int Id { get; set; }
    
            [Required(ErrorMessage = "Title is required")]
            public string Title { get; set; }
            [Required(ErrorMessage = "Subtitle is required")]
            public string Subtitle { get; set; }
    
            //[
            //    //ValidarEdad,
            //    Required(AllowEmptyStrings = false, ErrorMessage = "Es mandatorio proveer su fecha de Nacimiento."),
            //    Display(Name = "Fecha de Nacimiento:")
            //    , DataType(DataType.DateTime)
            //]
            public DateTime Nacimiento { get; set; }
    
            [Required(ErrorMessage = "Url is required"), Display(Name = "URL del Blog:")]
            public string Url { get; set; }
            public string Description { get; set; }
            public DateTime CreatedAt { get; set; }
            public DateTime ModifiedAt { get; set; }
            public int CreatedBy { get; set; }
            public int ModifiedBy { get; set; }
            public ICollection<Post> Posts { get; set; }
    
            [Required(ErrorMessage = "Author is required, kindly pick one!"), Display(Name ="Autor:")]
            public int? AuthorId { get; set; }
            public User Author { get; set; }
    
            public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
            {
    
                Debug.Write("----------------------------");
                Debug.Write("TEST TEST TEST");
                Debug.Write("----------------------------");
    
                //Blog myblog = (Blog)validationContext.ObjectInstance;          
    
                //if (Nacimiento > DateTime.Now)
                //{
                    yield return new ValidationResult("There's a problem with this date field!", new []{ nameof(Nacimiento) });
                //}
    
            }
        }

    Basically, I have multiple fields but I'm focusing on one field called "Nacimiento" which is a DateTime type, even if I commented on additional code and try to generate an error, nothing happens... I did try to post a message using the Debug.WriteLine to check if this class is doing something but nothing... it basically doesn't do anything, no error when running the validation of the form (server side), and not producing anything, no error messages, no compilation error messages also... please help.

    Tuesday, June 9, 2020 3:03 AM

Answers

  • User-121299044 posted

    Thank you! this gave me another idea.  In the meantime I think I found the answer, this is another Microsoft "by design" problem... In my model, I have round 4 or 5 properties with the [Required] but in my HTML form, I just included 2 of these required properties, including the one mentioned here... in other words, in order for the model to be completely validated, I should include all of my required properties in my form, not just 2 of them.

    For me, it makes sense, as I could request 2 of these from the customer and generate the other ones on my own... the problem is, the class validator never executes unless it has validated all the attributes in the model, otherwise it will never execute.  Before it executes, it requires all of the fields to be validated, but if the field does not exist because it was never in my HTML form, the end of the validation never occurs and the class is never called.  Basically, it's saying: "I could not validate the model or the model is not valid, why should I check for extra validations?" and does not run, even if we require it...

    The opposite occurs when I did create a custom Validation Attribute, it does execute with or without all the required fields in the HTML form. I hope this helps other people. :-)

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, June 9, 2020 2:01 PM

All replies

  • User-2054057000 posted

    Refer to this tutorial on Model validation in ASP.NET Core

    Tuesday, June 9, 2020 3:42 AM
  • User2078676645 posted

    Hi,

    This may be because you have not called Validate in the controller's response method, which you can reference by following these steps. Validated is used to determine if it has been verified, preventing it from being verified twice.

     public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
            {
                Blog myblog = validationContext.ObjectInstance as Blog;          
                if (myblog.Nacimiento > DateTime.Now)
                {
                    yield return new ValidationResult("There's a problem with this date field!", new[] { nameof(Nacimiento) });
                }
                Validated = true;
            }
            public bool Validated { get; set; }

    The method in Controller

    [HttpPost]
            public IActionResult valid(Blog blog)
            {
                if (!ModelState.IsValid)
                {
                    if (!blog.Validated)
                    {
                        var validationResults = blog.Validate(new ValidationContext(blog, null, null));
                        foreach (var error in validationResults)
                            foreach (var memberName in error.MemberNames)
                                ModelState.AddModelError(memberName, error.ErrorMessage);
                    }
                }
                return View("index");
            }

    Regards,

    Evern

    Tuesday, June 9, 2020 5:22 AM
  • User-121299044 posted

    Thank you! this gave me another idea.  In the meantime I think I found the answer, this is another Microsoft "by design" problem... In my model, I have round 4 or 5 properties with the [Required] but in my HTML form, I just included 2 of these required properties, including the one mentioned here... in other words, in order for the model to be completely validated, I should include all of my required properties in my form, not just 2 of them.

    For me, it makes sense, as I could request 2 of these from the customer and generate the other ones on my own... the problem is, the class validator never executes unless it has validated all the attributes in the model, otherwise it will never execute.  Before it executes, it requires all of the fields to be validated, but if the field does not exist because it was never in my HTML form, the end of the validation never occurs and the class is never called.  Basically, it's saying: "I could not validate the model or the model is not valid, why should I check for extra validations?" and does not run, even if we require it...

    The opposite occurs when I did create a custom Validation Attribute, it does execute with or without all the required fields in the HTML form. I hope this helps other people. :-)

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, June 9, 2020 2:01 PM