托管的 Blazor WASM GetFromJsonAsync:JSON 值无法转换为 System.Collections.Generic.IEnumerable`
Hosted Blazor WASM GetFromJsonAsync: The JSON value could not be converted to System.Collections.Generic.IEnumerable`
我尝试过挖掘和调试,但似乎无法弄清楚为什么 Http.Json.GetFromJsonAsync 无法转换。返回的错误如下(节选)
blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: The JSON value could not be converted to System.Collections.Generic.IEnumerable`1[Onero.Shared.StudentDTO]. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
System.Text.Json.JsonException: The JSON value could not be converted to System.Collections.Generic.IEnumerable`1[Onero.Shared.StudentDTO].
这是我的代码:
// In the blazor wasm client
public async Task<IEnumerable<StudentDTO>> GetStudentsAsync()
{
return await http.GetFromJsonAsync<IEnumerable<StudentDTO>>("api/Students");
}
// My controller
[HttpGet]
public async Task<ActionResult<IEnumerable<StudentDTO>>> GetStudents()
{
return await _context.Students
.Select(x => StudentToDTO(x))
.ToListAsync();
}
// My classes
public class StudentDTO
{
public long ID { get; set; }
public string Name { get; set; }
public ICollection<ExamScores> Results { get; set; }
}
public class Student
{
public long ID { get; set; }
public string Name { get; set; }
public ICollection<Guardian> Guardians { get; set; }
public ICollection<ExamScores> Results { get; set; }
}
public class ExamScores
{
public long ID{ get; set; }
public long StudentId { get; set; }
public Student Student { get; set; }
public Exam ExamType { get; set; }
public double Score { get; set; }
}
// Startup.cs ConfigureServices
services.AddDbContext<ResultsContext>(opt =>
opt.UseSqlite(Configuration.GetConnectionString("FirstPrototype")));
services.AddControllersWithViews()
.AddJsonOptions(
x => x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve
);
// Context
public class ResultsContext : DbContext
{
public ResultsContext(DbContextOptions<ResultsContext> options)
: base(options)
{
}
public DbSet<ExamScores> ResultsList { get; set; }
public DbSet<Student> Students { get; set; }
public DbSet<Guardian> Guardians { get; set; }
}
当我尝试记录控制器方法时,我从 _context 得到的实际上是
System.Collections.Generic.List`1[Onero.Shared.StudentDTO]
我不确定这是否与我设置数据库和迁移的方式有关?可能跟我的ConfigureServices
里的JsonSerializerOptions
有关?但如果确实如此,那么为什么我的控制器方法报告我正在取回我的对象列表,但我的客户端无法反序列化它?我会很感激 help/advice。谢谢
事实上是的,它确实与JsonSerializerOptions
有关。我必须在客户端中对我的 GetStudentsAsync
方法执行以下操作:
public async Task<IEnumerable<StudentDTO>> GetStudentsAsync()
{
var options = new JsonSerializerOptions()
{
ReferenceHandler = ReferenceHandler.Preserve,
PropertyNameCaseInsensitive = true
};
return await http.GetFromJsonAsync<IEnumerable<StudentDTO>>("api/Students", options);
}
我从 this 那里了解到,然后我突然想到 属性 名称可能因为大小写不匹配,这就是我将 PropertyNameCaseInsensitive
设置为 true 的原因。
我尝试过挖掘和调试,但似乎无法弄清楚为什么 Http.Json.GetFromJsonAsync 无法转换。返回的错误如下(节选)
blazor.webassembly.js:1 crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
Unhandled exception rendering component: The JSON value could not be converted to System.Collections.Generic.IEnumerable`1[Onero.Shared.StudentDTO]. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
System.Text.Json.JsonException: The JSON value could not be converted to System.Collections.Generic.IEnumerable`1[Onero.Shared.StudentDTO].
这是我的代码:
// In the blazor wasm client
public async Task<IEnumerable<StudentDTO>> GetStudentsAsync()
{
return await http.GetFromJsonAsync<IEnumerable<StudentDTO>>("api/Students");
}
// My controller
[HttpGet]
public async Task<ActionResult<IEnumerable<StudentDTO>>> GetStudents()
{
return await _context.Students
.Select(x => StudentToDTO(x))
.ToListAsync();
}
// My classes
public class StudentDTO
{
public long ID { get; set; }
public string Name { get; set; }
public ICollection<ExamScores> Results { get; set; }
}
public class Student
{
public long ID { get; set; }
public string Name { get; set; }
public ICollection<Guardian> Guardians { get; set; }
public ICollection<ExamScores> Results { get; set; }
}
public class ExamScores
{
public long ID{ get; set; }
public long StudentId { get; set; }
public Student Student { get; set; }
public Exam ExamType { get; set; }
public double Score { get; set; }
}
// Startup.cs ConfigureServices
services.AddDbContext<ResultsContext>(opt =>
opt.UseSqlite(Configuration.GetConnectionString("FirstPrototype")));
services.AddControllersWithViews()
.AddJsonOptions(
x => x.JsonSerializerOptions.ReferenceHandler = ReferenceHandler.Preserve
);
// Context
public class ResultsContext : DbContext
{
public ResultsContext(DbContextOptions<ResultsContext> options)
: base(options)
{
}
public DbSet<ExamScores> ResultsList { get; set; }
public DbSet<Student> Students { get; set; }
public DbSet<Guardian> Guardians { get; set; }
}
当我尝试记录控制器方法时,我从 _context 得到的实际上是
System.Collections.Generic.List`1[Onero.Shared.StudentDTO]
我不确定这是否与我设置数据库和迁移的方式有关?可能跟我的ConfigureServices
里的JsonSerializerOptions
有关?但如果确实如此,那么为什么我的控制器方法报告我正在取回我的对象列表,但我的客户端无法反序列化它?我会很感激 help/advice。谢谢
事实上是的,它确实与JsonSerializerOptions
有关。我必须在客户端中对我的 GetStudentsAsync
方法执行以下操作:
public async Task<IEnumerable<StudentDTO>> GetStudentsAsync()
{
var options = new JsonSerializerOptions()
{
ReferenceHandler = ReferenceHandler.Preserve,
PropertyNameCaseInsensitive = true
};
return await http.GetFromJsonAsync<IEnumerable<StudentDTO>>("api/Students", options);
}
我从 this 那里了解到,然后我突然想到 属性 名称可能因为大小写不匹配,这就是我将 PropertyNameCaseInsensitive
设置为 true 的原因。