Johan Vergeer
Johan Vergeer

Reputation: 5588

IValidatableObject implementation does not work

On my recipeline I wanted to create some validation logic for which I used the IValidateObject interface. After running I still get a yellow error message and when debugging I noticed that the Validat function has not even been called.

I hope someone could explain how I can get the validation to work properly.

 public class RecipeLine : IValidatableObject
    {
        [Display(Name = "Receptregel")]
        public string QuantityUomIngredient => $"{Quantity} {UnitOfMeasure?.Abbreviation ?? ""} {Ingredient?.Name ?? ""}";

    private RecipeApplicationDb db = new RecipeApplicationDb();

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        // Split the incoming string
        string[] valueAsString = QuantityUomIngredient.Split();

        if (QuantityUomIngredient != null)
        {
            // Check if the string has the proper length
            if (valueAsString.Length < 3)
            {
                var StringErrorMessage = "Er zijn onvoldoende gegevens ingevuld. voorbeeld: 1,2 kg Aardappelen";
                yield return new ValidationResult(StringErrorMessage);
            }

            // Check if the first value of the string is a double
            double quantityValue;
            bool quantity = double.TryParse(valueAsString[0], out quantityValue);
            if (!quantity)
            {
                var QuantErrorMessage = "De hoeveelheid moet een numerieke waarde zijn.";
                yield return new ValidationResult(QuantErrorMessage);
            }

            // Check if the UOM value exists in the database
            string uom = valueAsString[1];
            bool checkUOM = (from x in db.UnitOfMeasures where x.Abbreviation.ToLower() == uom select x).Count() > 0;

            if (!checkUOM)
            {
                var UomErrorMessage = "Er is geen juiste maateenheid ingevoerd.";
                yield return new ValidationResult(UomErrorMessage);
            }

            // Check if the ingredient exists in the database
            string ingredient = valueAsString[2];
            bool checkIngredient = (from x in db.Ingredients where x.Name.ToLower() == ingredient.ToLower() select x).Count() > 0;
            if (!checkIngredient)
            {
                var IngredientErrorMessage = "Er is geen juist ingredient ingevoerd.";
                yield return new ValidationResult(IngredientErrorMessage);
            }
        }
    }
}

Thanks in advance.

==================EDIT======================

Maybe this could also be important. In the controller I put a custom model binder. When debugging I noticed that I can't get to the validation function but it goes directly to db.savechanges.

    // POST: RecipeLine/Create
    [HttpPost]
    public ActionResult Create([ModelBinder(typeof(RecipeLineCustomBinder))] RecipeLine recipeLine)
    {
        ViewBag.ingredients = (from x in db.Ingredients select x).ToList();
        ViewBag.uom = (from x in db.UnitOfMeasures select x).ToList();
        if (ModelState.IsValid)
        {
            db.RecipeLines.Add(recipeLine);
            db.SaveChanges();
            return RedirectToAction("Create", new { id = recipeLine.RecipeId });
        }
        return View(recipeLine);
    }

Upvotes: 1

Views: 1276

Answers (1)

Ricardo Peres
Ricardo Peres

Reputation: 14555

IValidatableObject is only used if the attributes' validation succeeds.

Upvotes: 2

Related Questions