Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP.NET MVC "Ajax.BeginForm" executes OnSuccess even though model is not valid

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?

like image 255
Nippysaurus Avatar asked Sep 07 '11 04:09

Nippysaurus


People also ask

What is onsuccess and onfailure in Ajax?

1. OnSuccess – Name of the JavaScript function which will receive the response when the AJAX call is successful. 2. OnFailure – Name of the JavaScript function which will receive the response when the AJAX call fails. 3. LoadingElementId – ID of the element which will be displayed when the AJAX call is in progress.

What is the difference between ASP and jQuery unobtrusive Ajax?

ASP.NET MVC Ajax.BeginForm AjaxOptions custom arguments for OnSuccess, OnFailure. The jQuery Unobtrusive Ajax library complements jQuery Ajax methods by adding support for specifying options for HTML replacement via Ajax calls HTML5 data.

How to detect Ajax call in a form?

There is a Submit Button at the end of the Form and when the Button is clicked, the AJAX call is made. Finally there’s a hidden HTML DIV element which is displayed when the AJAX call is in progress. alert ("Error occured."); Abusive content.

How do I submit a form using Ajax?

There is a Submit Button at the end of the Form and when the Button is clicked, the AJAX call is made. Finally there’s a hidden HTML DIV element which is displayed when the AJAX call is in progress. alert ("Error occured."); No comments have been added to this article.


2 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.

like image 167
Serj Sagan Avatar answered Oct 07 '22 02:10

Serj Sagan


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
    }
}
like image 38
Darin Dimitrov Avatar answered Oct 07 '22 02:10

Darin Dimitrov