Почему возвращение моего AJAXoned Action не считается вызывающим?

В моем приложении ASP.NET MVC я получил этот вызов AJAX в разделе сценариев моего View:

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

Пошаговое действие вызываемого действия Controller:

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

... кажется, все работает нормально; "модель" содержит ожидаемое значение в UnitReportPairEmailVals.

Но я никогда не вижу предупреждающее сообщение отсюда в вызове Ajax:

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

Так почему же не достигается функция успеха вызова AQAX jQuery?

ОБНОВИТЬ

Кстати, это может быть подсказка: последняя строка моего метода Controller:

return View(model);

... красит слово "Вид" красным, как гребень петуха Род-Айленда. Но если это не должно быть, что это должно быть? Это то же самое, что у меня есть в конце моего действия "public ActionResult Index()", которое работает нормально.

ОБНОВЛЕНИЕ 2

Я изменил окончание моего вызова Ajax на:

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

... и конец моего метода контроллера:

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

... но я не получаю предупреждения ни от успеха, ни от неудачи.

ОБНОВЛЕНИЕ 3

Примечание: когда я попробовал это:

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

... "единица" была нулевой, и поэтому она не будет летать вообще.

Когда я изменил это на это (удалил строку 1 и изменил аргумент "data" обратно на то, что я использовал ранее):

$.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');
    }
});

... "единица" - это то, что я ожидаю (и "отчет" тоже), но в конечном итоге вижу "провал".

ОБНОВЛЕНИЕ 4

Как только я собрал несколько разных ответов на этот и другие вопросы, я написал совет о том, как это сделать, здесь.

ОБНОВЛЕНИЕ 5

У меня есть этот [рабочий] вызов ajax [рабочий]:

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

... но я не использую объявленную "модель", и, насколько я понимаю, она связана с "contentType: 'application/json',"

Поэтому я подумал, что вместо этого я должен сделать что-то вроде этого:

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

Теперь данные, передаваемые в метод контроллера, имеют строковый формат json (инкапсулированный в "модель").

Но это даже не работает.

Работает с первым блоком, но не со вторым.

Таким образом, я удалил обе строки "model" и "contentType" и изменил строку "data" на прежнюю, и она работает нормально. Так они бесполезны или я их неправильно использую?

2 ответа

Решение

Вот несколько фрагментов, которые я использую при выполнении ajax в 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;
        }
    });
});

Иногда эти два изменения (по сравнению с вашим оригиналом) не нужны, но ASP.NET может быть немного требователен, если json не совсем прав, и это помогает в этом. Так как вы можете использовать метод контроллера, это не было вашей проблемой, но это может быть удобно.

Ваша настоящая проблема заключалась в типе возврата в методе контроллера. ActionResult означает, что он будет искать соответствующее представление и создавать HTML на основе этого представления. Но если вы делаете ajax, то вы, вероятно, этого не хотите.

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

Это "стандартный" подход для вызовов ajax в ASP.NET MVC.

Как вы отметили в своем комментарии, ActionResult прекрасно работает в методе Index. Да, потому что целью метода index является загрузка страницы. Как правило, если метод используется для загрузки страницы, вы будете использовать ActionResult, потому что он будет использовать представление для создания HTML-кода для этой страницы. Но если вы просто отправляете информацию, а затем возвращаете ответ типа "успех", то вам не нужен полный HTML-ответ, вам нужен json. Вот почему JsonResult работает здесь.

Я подозреваю, что вы не создали представление для этого действия, и это вызвало бы сбой вызова ajax в случае исключения, так как механизм бритвы не сможет найти представление. Убедитесь, что View существует для этого действия, или если вы хотите вернуть другое представление, укажите что-то вроде:

 return View(model,"ViewName");

Вы также можете добавить сообщение об ошибке, чтобы увидеть, что происходит не так:

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

Обновить:

Если вы хотите только вернуть данные, используйте Json:

return Json(new {Result = model },JsonRequestBehavior.AllowGet);
Другие вопросы по тегам