无法使用 ajax 将数据从 JSONResult 传回处理程序

Cannot pass data from JSONResult back to handler using ajax

我想要以下工作流程:

  1. Ajax 调用页面模型处理程序以触发数据库并创建一些视图模型,return 结果为 JSONResult
  2. 将步骤 1 的结果传回另一个处理程序以重新加载局部视图

在第 1 步和第 2 步之间有一些使用 JS 的数据处理。但这超出了范围,因为数据只被读取而没有被更改。

第 1 步工作正常。但是第2步没有。这是一个简短的代码示例:

第一步: 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 returning 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;
        }

调用了重新加载局部视图的处理程序,但视图模型列表始终为空列表。

希望有人能给我指出正确的方向。

提前致谢!

改变这个:

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

为什么会这样

but the list of viewmodels is always an empty list.

那是因为您的服务器需要这样的查询字符串:

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 数组更改为 form-urlencoded 字符串,例如,如下更改 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 OnPostReloadCompaniesInAreaList([FormBody]List<CompanyInSearchAreaViewModel> companyInSearchAreaViewModels)
    {
        ...            
    }
    

    然后将 $.load() 替换为 :

    $.ajax({
       url: '@Request.Path?handler=ReloadCompaniesInAreaList',
       method:'POST',
       contentType:"application/json",
       data: searchResult,
       success: function(resp){
          $('#divSearchResult').html(resp)
       },
    });