【问题标题】:Razor Pages .Net Core passing a multi-layer JSON object with Children, parents and images back from MathodRazor Pages .Net Core 从 Mathod 传回带有子项、父项和图像的多层 JSON 对象
【发布时间】:2021-07-20 12:18:18
【问题描述】:

我有一个 Razor Pages .Net Core 应用程序,我在其中对一个方法进行 ajax 回调,以便检索更多记录以显示在屏幕上:

    public async Task<IActionResult> OnGetTimelineEntries(int pageIndex, int pageSize)
    {
        //System.Threading.Thread.Sleep(4000);

        ApplicationUser currentAppUser = await _userManager.GetUserAsync(User);

        PopulateUsersEntries(currentAppUser);
        GetHookUps(currentAppUser);

        foreach (ApplicationUser appUser in AppUsersList)
        {
            PopulateUsersEntries(appUser);
        }

        // The above code just populates the below Entries list:

        var pagedEntries = Entries
                            .Skip(pageIndex * pageSize)
                            .Take(pageSize);

        return new JsonResult(pagedEntries.Select(a => new
        {
            Comment = a.Comment,
            thumbNailImage = a.Trip.Season.AppUser.ApplicationUserImage.ImageDataThumb,
            IsEstimatedWeight = a.IsEstimatedWeight,
            tripTitle = a.Trip.Title,
            entryImagesCount = a.EntryImages.Count,
            tripSeasonTitle = a.Trip.Season.Title,
            appUserFirstName = a.Trip.Season.AppUser.FirstName,
            appUserLastName = a.Trip.Season.AppUser.LastName,
            entryTime = a.EntryTime.ToShortTimeString() + " - " + a.EntryTime.ToString("dd MMM yyyy"),
            isCatch = a.IsCatch,
            entryId = a.ID,
            imagesCount = a.EntryImages.Count,
            firstEntryImage = a.EntryImages.FirstOrDefault(),
            fishSpeciesDescription = a.FishSpecies.Description,
            fishWeightDescription = a.Weight + " " + a.WeightUnit.Description,
            entryImages = a.EntryImages


        }));

        //return new JsonResult(pagedEntries);
        //return new JsonResult(pagedEntries.Select(a => new { results = a }));

    }

如您所见,它返回一个 JSON 对象,我必须从该对象中选择我想要的字段,以将它们传递回一个“平面”JSON 对象。如果我尝试通过 JSON (return new JsonResult(pagedEntries);) 将整个 pagedEntries 对象传回,我会在 AJAX 结果中收到错误(根本没有太多信息可以诊断)。

$.ajax({
    url: '?handler=TimelineEntries',
    beforeSend: function (xhr) { xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val()); },
    data: { "pageindex": pageIndex, "pagesize": pageSize },
    type: "GET",
    success: function (data) {
        debugger;

        if (data != null) {
            for (var i = 0; i < data.length; i++) {
                $("#container").append("<h2>" +
                    data[i].comment +
                    "</h2 > "
                );
            }
            pageIndex++;
        }
    },
    beforeSend: function () {
        $("#progress").show();
    },
    complete: function () {
        $("#progress").hide();
    },
    error: function (e) {
        debugger;
        alert("Error while retrieving data!");
    }
});

有没有更好的方法可以将对象 pagedEntries 传递回部分视图 AJAX 调用,其所有子对象都完好无损,因此我不必将结果展平为一维 JSON 对象?

【问题讨论】:

    标签: json asp.net-core .net-core razor-pages


    【解决方案1】:

    您可以尝试使用ToList()。这是一个带有子对象的模型的工作演示:

    型号:

    public class Student
        {
            public int Id { get; set; }
            public int Age { get; set; }
            public string Name { get; set; }
            [ForeignKey("CourseId")]
            public Course Course { get; set; }
    
    
    
        }
     public class Course
        {
            public int Id { get; set; }
            public string Name { get; set; }
    
        }
    

    cshtml(我用0作为pageIndex,2作为pageSize,获取请求不需要XSRF-TOKEN):

    <div id="container"></div>
    <button onclick="sendajax()">click</button>
    @section scripts{
        <script>
            function sendajax() {
                var pageIndex = 0;
                var pageSize = 2;
            $.ajax({
                url: '?handler=TimelineEntries',
                data: { "pageindex": pageIndex, "pagesize": pageSize },
                type: "GET",
                dataType:"json",
                success: function (data) {
                    debugger;
    
                    if (data != null) {
                        for (var i = 0; i < data.length; i++) {
                            $("#container").append("<h2>" +
                                data[i].age +
                                "</h2 > "
                            );
                        }
                        pageIndex++;
                    }
                },
                beforeSend: function () {
                    $("#progress").show();
                },
                complete: function () {
                    $("#progress").hide();
                },
                error: function (e) {
                    debugger;
                    alert("Error while retrieving data!");
                }
            });
        }
        </script>
    } 
    

    cshtml.cs:

    public async Task<IActionResult> OnGetTimelineEntries(int pageIndex, int pageSize)
            {
                var s = _context.Student.Include(s => s.Course).Skip(pageIndex * pageSize).Take(pageSize).ToList();
                return new JsonResult(s);
    
            }
    

    结果:

    【讨论】:

    • 非常感谢,我能够在我不久前发布的答案中详细说明我的实际问题。我应该提到该对象已经是一个 IQueryable 列表。
    【解决方案2】:

    好的,所以当我能够进一步调试时,我发现如果我将模型剥离为仅包含单个子对象,它确实可以正常工作。我遇到的问题是:

    1. 父对象阻止成功(子对象正常)
    2. 大图

    对于父母对象,我做了一些研究,发现我需要确保我安装了最新的Microsoft.AspNetCore.Mvc.NewtonsoftJson 包:

    并且它在 Startup.cs 中被正确引用(public void ConfigureServices(IServiceCollection services) 方法:

    services.AddControllersWithViews()
        .AddNewtonsoftJson(options =>
        options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
    );
    

    为了确保我可以传递更大的图像和视频文件,到目前为止,这似乎可以解决问题(web.config

      <system.web.extensions>
        <scripting>
          <webServices>
            <jsonSerialization maxJsonLength="2147483647"/>
          </webServices>
        </scripting>
      </system.web.extensions>
    

    我现在在 ajax 中取回我的完整模型:成功函数,包括所有子对象、父对象和 base64 图像字符串。

    【讨论】:

      猜你喜欢
      • 2020-05-08
      • 2019-04-16
      • 2019-07-05
      • 2020-05-08
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      • 1970-01-01
      • 2019-07-25
      相关资源
      最近更新 更多