Razor Pages .Net Core 传递多层 JSON 对象,其中包含来自 Mathod 的子对象、父对象和图像

Razor Pages .Net Core passing a multi-layer JSON object with Children, parents and images back from Mathod

我有一个 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 对象,我必须 SELECT 我希望从对象中获得的字段将它们传回 'flat' 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 对象?

您可以尝试使用 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);

        }

结果:

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

  1. 父对象阻止成功(子对象没问题)
  2. 大图

对于 parents 对象,我做了一些研究,发现我需要确保安装了最新的 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 图像字符串。