с MVC 4.0 RedirectToAction не отображает PartialView как Partial, он отправляет целую страницу

У меня есть что-то сложное, но я не понимаю, почему это не сработает: у меня есть JSTree в моем Index.cshtml. Когда узел выбран, я делаю Ajax-вызов

public async Task<ActionResult> GetEBooksItems(string id)

которые возвращают частичное представление. Это работает СОВЕРШЕННО ХОРОШО.

Теперь, в дополнение к поиску по дереву, у меня есть форма для добавления некоторых критериев, чтобы сузить поиск. Я использую Ajax.BeginForm для отправки данных обратно в контроллер.

        public async Task<ActionResult> GetEBooksCustom(GenericSearchViewModel filter)
    {            
        vm = filter;
        //Session["GenreNodeId"] = id;
        Session["SearchCondition"] = (string.IsNullOrEmpty(vm.Condition) != true) ? vm.Condition : "All";
        Session["MaximumPrice"] = (string.IsNullOrEmpty(vm.MaxPrice) != true) ? vm.MaxPrice : "999999";
        Session["MinimumPrice"] = (string.IsNullOrEmpty(vm.MinPrice) != true) ? vm.MinPrice : "0";
        Session["SearchIndex"] = (string.IsNullOrEmpty(vm.SearchIndex) != true) ? vm.SearchIndex : "KindleStore";
        Session["SortOrder"] = (string.IsNullOrEmpty(vm.SortOrder) != true) ? vm.SortOrder : "price";
        Session["KeyWords"] = (string.IsNullOrEmpty(vm.Keywords) != true) ? vm.Keywords : "";
        Session["Title"] = (string.IsNullOrEmpty(vm.Title) != true) ? vm.Title : "";
        Session["Author"] = (string.IsNullOrEmpty(vm.Author) != true) ? vm.Author : "";
        return RedirectToAction("GetEBooksItems", new { id = vm.CategoryNodeId });                                    
    }

к этому методу, который, в свою очередь, вызывает первый с RedirectToAction.

Я пробовал все, что мог придумать, я всегда получаю результаты в виде целой страницы, а не частичного просмотра, как в первом методе.

Похоже, вызов GetEBooksCustom не «рассматривается» как вызов Ajax. Что мне не хватает? Спасибо за помощь, Бернард.

****Изменить через 6 часов***< em>*******

Между тем я сделал то, что было предложено, то есть извлек функциональные возможности из «GetEBooksItems», чтобы иметь возможность напрямую возвращать PartialView вместо использования RedirectToAction. В отладчике вроде все идеально, я вижу 200 ответ от сервера, НО все равно получаю полное отображение страницы, а url отображает метод контроллера, в то время как для ajax вызова такого быть не должно.

Дело в том, что у меня есть практически такая же форма где-то еще, где она работает как положено. Не вижу, что может быть иначе???

Как всегда, спасибо за вашу помощь и предложения. Бернар


person BernardG    schedule 21.04.2013    source источник


Ответы (2)


Я бы предположил, что это происходит потому, что RedirectToAction возвращает 302 вашему браузеру, буквально инструктируя его перенаправить на другое действие. Ваш браузер обрабатывает это, перенаправляя всю страницу. Вы должны (в зависимости от содержимого метода GetEBooksItems иметь возможность обойти это, просто вызвав другой метод напрямую вместо использования перенаправления:

return GetEBooksItems(vm.CategoryNodeId);

Или, что еще лучше, абстрагируйте логику из GetEBooksItems в отдельный метод, повторно используйте ее в GetEBooksCustom и верните PartialView напрямую. Таким образом, вам вообще не нужно работать с перенаправлением.

person Ant P    schedule 21.04.2013
comment
Да, это именно то, что я подумал, немного подумав об этом. Мне нужен метод, возвращающий основную часть vm, чтобы я мог вернуть его вместе с partialView вместо использования RedirectTo Action. Спасибо! Иногда достаточно просто спросить и посмотреть второй парой глаз, чтобы получить ответ.... :-) - person BernardG; 21.04.2013

В итоге я использовал плагин jQuery Form вместо Ajax.BeginForm. После потери часов на это мне потребовалось около 10 минут, чтобы заставить его работать точно так, как ожидалось!

Для тех, кому это может быть интересно, вот 2 типа кодирования один над другим:

    //using (Ajax.BeginForm("GetEBooksCustom", "Home", new AjaxOptions {
    //                            UpdateTargetId = "ListOfBooksHere", 
    //                          HttpMethod = "POST",                                    
    //                          OnBegin="ShowProcessingMsg",
    //                          OnComplete="HideProcessingMsg"


    $("#eBooksForm").ajaxForm({
        url: "/home/GetEBooksCustom",
        type: "POST",
        success: function(data) {
            $("#ListOfBooksHere").html(data);
        }
    });

Я не стал заморачиваться с OnBegin и OnComplete, так как использую это:

    $(document).ajaxSend(function() {
        $('.loadingIndicator').show();
    });

    $(document).ajaxComplete(function() {
        $('.loadingIndicator').hide();
    });
person BernardG    schedule 22.04.2013