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);
}
结果:
好的,所以当我能够进一步调试时,我发现如果我将模型剥离回仅包含单个子对象,它确实可以正常工作。我遇到的问题是:
- 父对象阻止成功(子对象没问题)
- 大图
对于 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 图像字符串。
我有一个 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);
}
结果:
好的,所以当我能够进一步调试时,我发现如果我将模型剥离回仅包含单个子对象,它确实可以正常工作。我遇到的问题是:
- 父对象阻止成功(子对象没问题)
- 大图
对于 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 图像字符串。