Let's say I have a standard form setup with a ViewModel and validation like this.
ViewModel
public class EditEventViewModel
{
public int EventID { get; set; }
[StringLength(10)]
public string EventName { get; set; }
}
Form in the View
@using (Html.BeginForm(null, null, FormMethod.Post, new {id="editEventForm"}))
{
@Html.AntiForgeryToken()
@Html.LabelFor(model => model.EventName)
@Html.EditorFor(model => model.EventName)
@Html.ValidationMessageFor(model => model.EventName)
}
Controller
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "EventName")] EventViewModel model)
{
//Get the specific record to be updated
var eventRecord = (from e in db.Event
where e.EventID == model.EventID
select e).SingleOrDefault();
//Update the data
if (ModelState.IsValid)
{
eventRecord.EventName = model.EventName;
db.SaveChanges();
}
return RedirectToAction("Index");
}
Now, if I do a regular form submit and enter an EventName with a string length over 10, the model error will be triggered and I'll be notified in the validation message in the view.
But, I prefer to submit my forms with JQuery AJax like this.
$.ajax({
type: "POST",
url: "/EditEvent/Edit",
data: $('#editEventForm').serialize(),
success: function () {
},
error: function () {
}
});
With this way, I add some javascript on the client side to validate before the submit, but I'd still like the data annotations in the ViewModel as a backup.
When this reaches the controller, it's still checked with if (ModelState.IsValid)
. If it's not valid, then the data is not written to the database, just as designed.
Now, I want to know what I can do if the ModelState is not valid, when posting with JQuery. This will not trigger the regular validation, so what can I do to send back information that an error has occurred?
if (ModelState.IsValid)
{
eventRecord.EventName = model.EventName;
db.SaveChanges();
}
else
{
//What can I do here to signify an error?
}
Update With Further Information
I already have custom errors set up in Web.config
<customErrors mode="On">
That routes errors to the Views/Shared/Error.cshtml file, where I'm outputting information about the error that got the request there. Is there anyway my model state error (or any error) in the controller could be sent here?
@model System.Web.Mvc.HandleErrorInfo
@{
Layout = null;
ViewBag.Title = "Error";
}
<h1 class="text-danger">Error.</h1>
<h2 class="text-danger">An error occurred while processing your request.</h2>
<p>
Controller: @Model.ControllerName <br />
Action: @Model.ActionName <br />
Exception: @Model.Exception.Message
</p>
UPDATE again
Here's another update working with pieces of all of the responses.
In my controller, I put this in the else statement throw new HttpException(500, "ModelState Invalid");
(else - meaning that the ModelState is not valid)
That triggers my custom errors in Web.config to send to the Views/Shared/Error.cshtml, (kind of) but this only shows up in FireBug like this. The actual page doesn't go anywhere. Any idea how I get this on the parent page? If this doesn't make sense, I've been using the setup described here, to send to my custom error page. The fact that this is an AJAX call is making this work a little differently.