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

喜夏-厌秋 提交于 2019-12-12 05:59:51

问题


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.

UPDATE 3

Note: When I tried this:

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;
        }
    });

..."unit" was null, and so it wouldn't fly at all.

When I changed it to this (removed line 1 and changed the "data" arg back to what I had been using previously):

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

..."unit" is what I expect it to be (and "report", too), but I ultimately see 'failed'.

UPDATE 4

Once I pieced together several different answers to this and related questions, I wrote up a tip on how to do this here.

UPDATE 5

I've got this [working] ajax call [working]:

var model = JSON.stringify({ unit: unitval, report: 1 });
$.ajax({
    type: 'GET',
    url: '@Url.Action("GetUnitDataRangeParamsVals", "UnitReportDataRangeParams")',
    data: { unit: unitval, report: 1 },
    contentType: 'application/json',
    cache: false,
    success: function (returneddata) {
        populatedatarangeprams(1, returneddata);
    },
    error: function () {
        alert('error - returneddata.error.stringify');
    }
});

...but I'm not using the "model" that's declared and, according to my understanding, it is paired with "contentType: 'application/json',"

So I thought what I should do is something like this instead:

var model = JSON.stringify({ unit: unitval, report: 1 });
$.ajax({
    type: 'GET',
    url: '@Url.Action("GetUnitDataRangeParamsVals", "UnitReportDataRangeParams")',
    data: model,
    contentType: 'application/json',
    cache: false,
    success: function (returneddata) {
        populatedatarangeprams(1, returneddata);
    },
    error: function () {
        alert('error - returneddata.error.stringify');
    }
});

Now the data passed to the controller's method is in json stringified format (encapsulated in "model").

But, it doesn't even work.

It works with the first block, but not the second.

So I removed both the "model" and the "contentType" lines, and changed the "data" line back to what it had been, and it works fine. So are they useless, or am I employing them wrongly?


回答1:


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.




回答2:


I suspect you do not have created the view for this action and that would cause ajax call to fail in case of exception as razor engine will not be able to find the View. Make sure View exists for this action or if you want to return some other view specify that like:

 return View(model,"ViewName");

you can also add failure call back to see what is going wrong:

success: function (result) {
            alert(result);
        },
error: function(error){
           console.log(error);
        }

Update:

If you only want to return data then use Json:

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


来源:https://stackoverflow.com/questions/36780506/why-is-my-ajaxoned-actions-return-not-being-seen-as-successful-by-the-caller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!