Lorenzo
Lorenzo

Reputation: 29427

How handle different results in an ajax call?

Suppose you have the following controller action

[HttpPost]
public ActionResult Save( CustomerModel model )
{
    if (!ModelState.IsValid) {
        //Invalid - redisplay form with errors
        return PartialView("Customer", model);
    }
    try {
        //
        // ...code to save the customer here...
        //
        return PartialView( "ActionCompleted" );
    }
    catch ( Exception ex ) {
        ActionErrorModel aem = new ActionErrorModel() { 
            Message = ex.Message 
        };
        return PartialView( "ActionError", aem );
    }
}

And suppose you call this action using jQuery:

$.ajax({
    type: "post",
    dataType: "html",
    url: "/Customer/Save",
    sync: true,
    data: $("#customerForm").serialize(),
    success: function(response) {
        /*
             ??????
        */
    },
    error: function(response) {
    }
});

I would like to be able to distinguish between the results I am getting to handle them in different ways on the client. In other words how can I understand that the action

Any suggestion?

Upvotes: 0

Views: 214

Answers (2)

Darin Dimitrov
Darin Dimitrov

Reputation: 1038790

One way to handle this is to append a custom HTTP header to indicate in which case we are falling:

[HttpPost]
public ActionResult Save( CustomerModel model )
{
    if (!ModelState.IsValid) {
        //Invalid - redisplay form with errors
        Response.AppendHeader("MyStatus", "case 1");
        return PartialView("Customer", model);
    }
    try {
        //
        // ...code to save the customer here...
        //
        Response.AppendHeader("MyStatus", "case 2");
        return PartialView( "ActionCompleted" );
    }
    catch ( Exception ex ) {
        ActionErrorModel aem = new ActionErrorModel() { 
            Message = ex.Message 
        };
        Response.AppendHeader("MyStatus", "case 3");
        return PartialView( "ActionError", aem );
    }
}

And on the client side test this header:

success: function (response, status, xml) {
    var myStatus = xml.getResponseHeader('MyStatus');
    // Now test the value of MyStatus to determine in which case we are
}

The benefit of this is that the custom HTTP header will always be set in the response no matter what content type you've returned. It will also work with JSON, XML, ...

Remark 1: To avoid cluttering you controller action with all those Response.AppendHeader instructions you could write a custom ActionResult allowing you to directly specify the value of this header so that you simply return this.MyPartialView("Customer", model, "case 1")

Remark 2: Remove this sync: true attribute from the request because it makes my eyes hurt (in fact I think you meant async: 'false').

Upvotes: 2

Nick Craver
Nick Craver

Reputation: 630389

You could check for an element unique to that view, for example:

$.ajax({
    type: "post",
    dataType: "html",
    url: "/Customer/Save",
    sync: true,
    data: $("#customerForm").serialize(),
    success: function(response) {
        var resp = $(response);
        if($(resp.find("#customer").length) {
          //customer returned
        } else if($(resp.find("#completed").length) {
          //completed view
        } else if($(resp.find("#error").length) {
          //error view
        }
    },
    error: function(response) {
    }
});

Upvotes: 0

Related Questions