I have a "submit feedback" form which uses "Ajax.BeginForm" to render a partial containing the form elements. The OnSuccess event is triggering even if the ModelState is not valid. Is this normal? I was expecting to be able to do a few postbacks resulting in an invalid model, then when the model is valid and there are no errors then the OnSuccess event would trigger?
-
I agree that this is needlessly complex to work with. We obviously need a simple value that indicates whether or not the model is valid. – Don Rolling Jan 12 '17 at 16:54
5 Answers
I handle this issue with a fairly simple javascript technique:
First setup your OnSuccess
like this:
OnSuccess = "UpdateSuccessful(data)"
Then your javascript function like this:
function UpdateSuccessful(data) {
if (data.indexOf("field-validation-error") > -1) return;
// Do your valid stuff here
}
This way, there is no need to mess with your controller, or more importantly, your controller can return the Partial View
with the model errors without doing anything weird, ie:
public ActionResult SaveDetails(Project model)
{
if (ModelState.IsValid)
{
model.SaveProject();
}
return PartialView("ProjectForm", model);
}
And in your AjaxOptions
:
UpdateTargetId = "FormContents"
Now just make sure you have a div
or something with id="FormContents"
wherever you want your form displayed.

- 28,927
- 17
- 154
- 183
-
1
-
Does this **'data'** object works on all browsers ? does it have any limitations or compatibility issues at all ? – Ali Sep 03 '14 at 06:21
-
-
I use @Html.ValidationSummary() so need to check this: if (data.indexOf("validation-summary-errors") > -1) – Omid.Hanjani Jun 02 '16 at 09:38
-
Is this normal?
Yes, of course. If the server sends HTTP 200 the OnSuccess method is called. The notion of modelstate validity is server side only. As long as your controller action returns some view/partial/json/... the OnSuccess will trigger. If an exception is thrown inside your controller action then the OnError will be triggered instead of OnSuccess.
So in order to handle this case you could have your controller action do something along the lines of:
[HttpPost]
public ActionResult Process(MyViewModel model)
{
if (!ModelState.IsValid)
{
return Json(new { success = false });
}
return Json(new { success = true });
}
and then:
function success(result) {
if (result.success) {
// the model was valid
} else {
// the model was invalid
}
}
Now in the case of invalid model you might want to show the error messages to the user by refreshing the form. What you could do in this case is place your form inside a partial and in the event of an invalid modelstate you would return a partialview from your controller action and in the case of success a json object. So in your success handler you could test:
function success(result) {
if (result.success) {
// the model was valid
} else {
// there were errors => show them
$('#myform_container').html(result);
// if you are using client side validation you might also need
// to take a look at the following article
// http://weblogs.asp.net/imranbaloch/archive/2011/03/05/unobtrusive-client-side-validation-with-dynamic-contents-in-asp-net-mvc.aspx
// and reattach the client validators to the form as you are
// refreshing its DOM contents here
}
}

- 1,023,142
- 271
- 3,287
- 2,928
-
4Thank you thank you. This answer is perfect. I'm surprised there isn't a solid documentation on handling this scenario (model errors) with the unobtrusive AJAX stuff. – Nicholas Head Feb 16 '12 at 22:04
-
2Doesn't work for me because, on failure, I have to return a view, not a JSON. – Misi Oct 30 '14 at 11:18
-
I think first you have to check the type of the result: if (typeof(result) == "object" && result.success) { – Misi Oct 30 '14 at 11:28
-
I do this in a partial view and in error need to reload partial view so use 'replaceWith' instead of 'html': $('#myform_container').replaceWith(result); – Omid.Hanjani Jun 02 '16 at 09:41
You can do the following:
var OnSuccess = function() {
if ($(".validation-summary-errors").length == 0) {
//Your javascript/jquery code goes here
}
}

- 6,188
- 9
- 39
- 60

- 8,334
- 9
- 46
- 68
Slight variation on Luis' answer:
function OnSuccess() {
if ($("span[class='field-validation-error']").length == 0) {
alert("Target Platform saved Successfully.");
}
}

- 67
- 1
- 7
I return a bad request instead of the View to ensure that the ajax call returns onfail and not onsuccess.
In the xhr.statustext you can find the string written in the bad request and manage correctly the onfail event.
Server side:
if (!ModelState.IsValid)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Model not valid");
}
Client side:
$.ajax({
url: '',
method: 'POST'
}).fail(function (xhr) {
alert(xhr.statustext);
});

- 201
- 2
- 5