Невозможно передать данные из JSONResult обратно в обработчик, используя ajax - PullRequest
0 голосов
/ 16 февраля 2020

Я хотел бы иметь следующий рабочий процесс:

  1. Ajax вызов обработчика модели страницы для запуска базы данных и создания некоторых моделей представления и возврата результата в виде JSONResult
  2. Передайте результат шага 1 другому обработчику, чтобы перезагрузить частичное представление

Между шагами 1 и 2 происходит некоторая обработка данных с использованием JS. Но это выходит за рамки, поскольку данные только читаются и не изменяются.

Шаг 1 работает нормально. Но шаг 2 не делает. Вот краткий пример кода:

Шаг 1: Ajax:

            var searchArea = parseFloat(document.getElementById('txtSearchArea').value);
            var latitude = parseFloat(document.getElementById('hiddenLat').value);
            var longitude = parseFloat(document.getElementById('hiddenLong').value);

            var requestData = JSON.stringify({'latitude': latitude, 'longitude': longitude, 'searchArea': searchArea});

            $.ajax({
                type: "POST",
                url: '@Request.Scheme://@Request.Host@Request.Path?handler=GetCompaniesWithinSearchArea',
                headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                data: requestData
            }).fail(function (x) {
                alert('Error fetching companies in search area.');
            }).done(function (result) {
                reloadSearchResultPartialView(result);
            });

C#:

        public async Task<JsonResult> OnPostGetCompaniesWithinSearchAreaAsync([FromBody] LatitudeLongitudeSearchArea latitudeLongitudeSearchArea)
        {
            var latitude = latitudeLongitudeSearchArea.Latitude;
            var longitude = latitudeLongitudeSearchArea.Longitude;
            var searchArea = latitudeLongitudeSearchArea.SearchArea;

            var idsOfcompaniesInArea = await _companiesService.GetIdsOfCompaniesWithinSearchAreaAsync(latitude, longitude, searchArea));

            var companyInSearchAreaVMs = await _companiesInSearchAreaViewModelFactory.Create(idsOfcompaniesInArea);

            return new JsonResult(companyInSearchAreaVMs);
        }

с _companiesInSearchAreaViewModelFactory.Create возвращением List<CompanyInSearchAreaViewModel> .

Шаг 2: Обычно я использую метод javascript load(...), чтобы вызвать перезагрузку частичного представления. Поэтому я пытался использовать этот подход снова.

JS:

function reloadSearchResultPartialView(searchResult) {
$('#divSearchResult').load('@Request.Scheme://@Request.Host@Request.Path?handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels=' + searchResult);
}

, где searchResult - результат ответа шага 1. Данные не изменялись между шагами 1 и 2.

C# - это обработчик для перезагрузки частичного представления.

        public PartialViewResult OnGetReloadCompaniesInAreaList(List<CompanyInSearchAreaViewModel> companyInSearchAreaViewModels)
        {
            var result = new PartialViewResult
            {
                ViewName = "_CompaniesInAreaList",
                ViewData = new ViewDataDictionary<IList<CompanyInSearchAreaViewModel>>(ViewData, companyInSearchAreaViewModels)
            };

            return result;
        }

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

Надеюсь, кто-нибудь подскажет мне правильное направление.

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 17 февраля 2020

Почему это происходит

, но список моделей представления всегда является пустым списком.

Это потому, что ваш сервер ожидает строку запроса, подобную этой:

handler=ReloadCompaniesInAreaList
&[0].prop1= 11
&[0].prop2=12
...
&[1].prop1=21
&[1].prop2=22
...

Однако, используя

$('#divSearchResult').load('@Request.Scheme://@Request.Host@Request.Path?handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels=' + searchResult);

Вы отправляете строку запроса как:

handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels=[object

Как исправить

Есть несколько способов исправить эта проблема.

  1. Самый простой способ - изменить массив json на строку в форме кода, например, изменить функцию reloadSearchResultPartialView(), как показано ниже:

    function reloadSearchResultPartialView(searchResult) {
        //$('#divSearchResult').load('@Request.Scheme://@Request.Host@Request.Path?handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels=' + searchResult);
        $('#divSearchResult').load('@Request.Path?handler=ReloadCompaniesInAreaList', $.param(createFormUrlEncodedPayload("",searchResult)));
    }
    // my helper function that recursively convert a plain js obj to a form-urlencoded string
    function createFormUrlEncodedPayload(name,o){
        var payload = {};
        function _objectNotNull(value){ return value !== null && typeof value === "object"; }
        function _create(prefix,obj) {
            for(var prop in obj) {
                if (obj.hasOwnProperty(prop)) {
                    var key =prefix?
                        (isNaN(prop)? key = prefix + "." + prop : key = prefix + ".[" + prop + "]") :
                        (isNaN(prop)? key = prop : key = "[" + prop + "]");
                    var value = obj[prop];
                    if(_objectNotNull(value)) 
                        _create(key, value); 
                    else 
                        payload[key]=value;
                }
            }
        };
        _create(name,o);
        return payload;
    }
    
  2. Или, в качестве альтернативы, вы можете заставить свой сервер получать HTTP POST запрос вместо GET,

    public PartialViewResult On<b>Post</b>ReloadCompaniesInAreaList(<b>[FormBody]</b>List<CompanyInSearchAreaViewModel> companyInSearchAreaViewModels)
    {
        ...            
    }
    

    и затем заменить $.load() на :

    $.ajax({
       url: '@Request.Path?handler=ReloadCompaniesInAreaList',
       method:'POST',
       contentType:"application/json",
       data: searchResult,
       success: function(resp){
          $('#divSearchResult').html(resp)
       },
    });
    
1 голос
/ 16 февраля 2020

Измените это:

function reloadSearchResultPartialView(searchResult) {
   $('#divSearchResult').load('@Request.Scheme://@Request.Host@Request.Path?handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels=' + searchResult);
}

на

function reloadSearchResultPartialView(searchResult) {
     var arrStr = encodeURIComponent(JSON.stringify(searchResult));
     $('#divSearchResult').load('@Request.Scheme://@Request.Host@Request.Path?handler=ReloadCompaniesInAreaList&companyInSearchAreaViewModels='+arrStr);
 }

И в PageModel

public PartialViewResult OnGetReloadCompaniesInAreaList(List<CompanyInSearchAreaViewModel> companyInSearchAreaViewModels)
        {
            var result = new PartialViewResult
            {
                ViewName = "_CompaniesInAreaList",
                ViewData = new ViewDataDictionary<IList<CompanyInSearchAreaViewModel>>(ViewData, companyInSearchAreaViewModels)
            };

            return result;
        }

на

public PartialViewResult OnGetReloadCompaniesInAreaList(string companyInSearchAreaViewModels)
{
            List<CompanyInSearchAreaViewModel> data = JsonConvert.DeserializeObject<List<CompanyInSearchAreaViewModel>>(companyInSearchAreaViewModels);

            var result = new PartialViewResult
            {
                ViewName = "_CompaniesInAreaList",
                ViewData = new ViewDataDictionary<IList<CompanyInSearchAreaViewModel>>(ViewData, data)
            };

            return result;
}
...