【问题标题】:Cannot pass data from JSONResult back to handler using ajax无法使用 ajax 将数据从 JSONResult 传递回处理程序
【发布时间】:2020-05-31 07:18:47
【问题描述】:

我想要以下工作流程:

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

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

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

第 1 步: 阿贾克斯:

            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&lt;CompanyInSearchAreaViewModel&gt;

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

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

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

提前致谢!

【问题讨论】:

    标签: c# ajax asp.net-core razor-pages


    【解决方案1】:

    改变这个:

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

    【讨论】:

      【解决方案2】:

      为什么会发生

      但视图模型列表始终是一个空列表。

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

      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 companyInSearchAreaViewModels)
        {
            ...
        }
        

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

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

      【讨论】:

      • 感谢您的有用解释。不幸的是,我无法让它工作。因此我选择@SerhatDev 的答案是正确的。
      猜你喜欢
      • 1970-01-01
      • 2012-11-28
      • 1970-01-01
      • 2020-12-10
      • 2021-06-29
      • 2020-01-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多