2

Is there a way I can override the default validation error that is thrown up for a model property from the controller? For example, the car.make cannot be null, but I want to throw a specific error if the person spells the name of the car make wrong.:

MODEL

public class Car
{
    public int ID { get; set; }
    [Required]
    public string Make { get; set; }
}

VIEW

<div class="form-group">
       @Html.EditorFor(model => model.Make, new { htmlAttributes = new { @class = "form-control" } })
       @Html.ValidationMessageFor(model => model.Make, "", new { @class = "text-danger" })
</div>

CONTROLLER

public ActionResult Create([Bind(Include = "Make,Model")] Car car)
{
    ModelState.AddModelError("Car.Make", "Check your spelling");
    return View(car);
}
1
  • 2
    Its not .AddModelError("Car.Make", ...) its .AddModelError("Make", ...) - you model does not contain a property named Car. But if you only want to select from valid values, consider using a <select> element (or a jQuery autocomplete) Commented Jun 14, 2016 at 2:57

4 Answers 4

7

Just you need to modify the ModelState.AddModelError("Car.Make", "Check your spelling"); method like

public ActionResult Create([Bind(Include = "Make,Model")] Car car)
{
     if(//Your Condition upon which you want to model validation throw error) {
        ModelState.AddModelError("Make", "Check your spelling");
      }
     if (ModelState.IsValid) {
       //Rest of your logic 
     }
   return View(car);
 }

Better approach is to keep the validation logic out of the controller. And if you want to do that you need to create you custom annotation based on your validation logic. To Create a custom annotation you need to create new class and implement the ValidationAttribute in your class.

 public class SpellingAttributes: ValidationAttribute  
 {
 } 

Next step you need to override the IsValid() and write you validation logic inside that

protected override ValidationResult IsValid(object value, ValidationContext validationContext)  
{  
    //validation logic 

   //If validation got success return ValidationResult.Success;
    return ValidationResult.Success;  
} 

And In your model class you can directly use this annotation like

public class Car
{
     public int ID { get; set; }
     [Required]
     [Spelling(ErrorMessage ="Invalid Spelling")
     public string Make { get; set; }
}

For more details about how to create a custom annotation in MVC you can refer my blog here Hope it helps you.

Sign up to request clarification or add additional context in comments.

1 Comment

My form uses ajax to check if what the user submitted for car.make is valid before actually submitting the form. In order to validate what the user is submitting I need to pass the form value as a variable to the DataAnnotation. However I do not think this is possible. after reading this post. Is this the case? stackoverflow.com/questions/21680554/…
2

I would implemet custom DataAnnotation attribute and use it for Car.Make property validation.

Here you have skeleton of its implementation:

public class CheckSpellingAttribute : ValidationAttribute
{
    public override bool IsValid(object value)
    {
        string stringValue = value as string;
        if (string.IsNullOrEmpty(stringValue) != false)
        {
            //your spelling validation logic here
            return isSpellingCorrect(stringValue );
        }
        return true;
   }
}

and later you can use it on your model like this:

public class Car
{
     public int ID { get; set; }

     [Required]
     [CheckSpelling(ErrorMessage = "Check your spelling")]
     public string Make { get; set; }
}

your view will not change and action will be much simpler

public ActionResult Create([Bind(Include = "Make,Model")] Car car)
{
    return View(car);
}

Comments

0

The create method in your controller should be something like below:

public ActionResult Create([Bind(Include = "Make,Model")] Car car)
{
    if(!checkSpelling(car.Make)) {
        ModelState.AddModelError("Make", "Check your spelling");
    }
    if (ModelState.IsValid) {
        //Save changes
    }
    return View(car);
}

You will notice that the first argument key for the method ModelState.AddModelError(string key, string errorMessage) should be just "Make" in your case. Ref: MSDN

Anyhow, I would recommend implementing a custom ValidationAttribute similar to this example.

Comments

0
public ActionResult Create([Bind(Include = "Make,Model")] Car car)
{
    if (ModelState["Make"] == null)
    {
        var innerModelState = new ModelState();
        innerModelState.Errors.Add("Check your spelling");
        ModelState.Add(new KeyValuePair<string, System.Web.Mvc.ModelState>("Make", innerModelState));
    }

    return View(car);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.