简体   繁体   中英

Adding custom error message for model property

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);
}

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.

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);
}

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 .

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM