B. Clay Shannon B. Clay Shannon - 7 months ago 11
Javascript Question

Why is my AJAXoned Action's return not being seen as successful by the caller?

In my ASP.NET MVC app, I've got this AJAX call in my View's script section:

$(".ckbx").change(function () {
. . .
$.ajax({
type: 'GET',
url: '@Url.Action("GetUnitReportPairVals", "Home")',
data: { unit: unitval, report: rptval },
cache: false,
success: function (result) {
alert(result);
}
});
});


Stepping through the Controller action being called:

public ActionResult GetUnitReportPairVals(string unit, string report)
{
HomeModel model = new HomeModel();

int rptId = GetReportIDForName(report);

DataTable UnitReportPairEmailValsDT = new DataTable();
UnitReportPairEmailValsDT = SQL.ExecuteSQLReturnDataTable(
SQL.UnitReportPairEmailQuery,
CommandType.Text,
new SqlParameter()
{
ParameterName = "@Unit",
SqlDbType = SqlDbType.VarChar,
Value = unit
},
new SqlParameter()
{
ParameterName = "@RptID",
SqlDbType = SqlDbType.Int,
Value = rptId
}
);

model.UnitReportPairEmailVals = UnitReportPairEmailValsDT;
return View(model);
}


...it all seems to be working fine; "model" contains the expected value in UnitReportPairEmailVals.

But I never see the alert message from here in the Ajax call:

success: function (result) {
alert(result);
}


So why is the "success" function of the jQuery AJAX call not being reached?

UPDATE



BTW, this may be a clue: the final line of my Controller method:

return View(model);


...paints the word "View" red as a Rhode Island rooster's comb. But if it's not supposed to be that, what is it supposed to be? That's the exact same thing I have at the end of my "public ActionResult Index()" controller Action, which works fine.

UPDATE 2



I changed the end of my Ajax call to:

success: function (result) {
alert(result);
},
failure: function (error) {
alert(error);
}


...and the end of my Controller method to:

return Json(new { Result = model }, JsonRequestBehavior.AllowGet);


...but I get no alert, neither from success nor from failure.

Answer

Here are a few snippets I use when doing ajax in ASP.NET MVC.

$(".ckbx").change(function () {
    .....
    var model = JSON.stringify({ unit: unitval, report: rptval });
    $.ajax({
        type: 'GET',
        url: '@Url.Action("GetUnitReportPairVals", "Home")',
        data: model,
        contentType: 'application/json',
        cache: false,
        success: function (result) {
            alert(result);
        },
        error: function(result) {
            debugger;
        }
    });
});

Sometimes those two changes (as compared to your original) are not necessary but ASP.NET can be slightly picky if the json isn't just right and this helps with that. Since you are able to step into the controller method, this wasn't your problem, but it can be handy.

Your real problem was the return type on the controller method. ActionResult means it is going to look for a corresponding view and build out the html based on that view. But if you are doing ajax then you probably don't want that.

public JsonResult GetUnitReportPairVals(string unit, string report)
{
    // do some stuff
    // then create response model
    var model = ...//whatever data you are returning here
    return Json(model);
}

This is the "standard" approach for ajax calls in ASP.NET MVC.

As you noted in your comment, ActionResult works great in the Index method. Yes, because the purpose of the index method is to load a page. Generally, if the method is used to load a page then you'll use ActionResult because it will use a view to create the html for that page. But if you are just submitting info and then returning a response like "success" then you don't want a whole html response, you want json. That's why JsonResult works here.