Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I add a ModelState.AddModelError from a Model class (rather than the controller)?

Tags:

asp.net-mvc

I want to display an error to the user in an ASP.MVC 3 input form using ModelState.AddModelError() so that it automatically highlights the right field and puts the error next to the particular field.

In most examples, I see ModelState.AddModelError() and if(ModelState.IsValid) placed right in the Controller. However, I would like to move/centralize that validation logic to the model class. Can I have the model class check for model errors and populate ModelState.AddModelError()?

Current Code:

// Controller
[HttpPost]
public ActionResult Foo(Bar bar)
{  
    // This model check is run here inside the controller.
    if (bar.isOutsideServiceArea())
        ModelState.AddModelError("Address", "Unfortunately, we cannot serve your address.");

    // This is another model check run here inside the controller.
    if (bar.isDuplicate())
        ModelState.AddModelError("OrderNumber", "This appears to be a duplicate order");

    if (ModelState.IsValid)
    {
        bar.Save();
        return RedirectToAction("Index");
    }
    else
        return View(bar)
}

Desired Code:

// Controller
[HttpPost]
public ActionResult Foo(Bar bar)
{  
    // something here to invoke all tests on bar within the model class

    if (ModelState.IsValid)
    {
        bar.Save();
        return RedirectToAction("Index");
    }
    else
        return View(bar)
}


...
// Inside the relevant Model class
if (bar.isOutsideServiceArea())
    ModelState.AddModelError("Address", "Unfortunately, we cannot serve your address.");

if (bar.isDuplicate())
    ModelState.AddModelError("OrderNumber", "This appears to be a duplicate order");
like image 483
Dan Sorensen Avatar asked Jun 21 '11 22:06

Dan Sorensen


2 Answers

If you are using MVC 3, you should checkout IValidatableObject, it's what you're after.

Scott Gu mentions it in his MVC3 Intro blog posting.

like image 98
Charlino Avatar answered Oct 04 '22 04:10

Charlino


You can do something like this using custom data annotations or using RuleViolations like what they did in the NerdDinner example.

like image 37
John Kalberer Avatar answered Oct 04 '22 04:10

John Kalberer