首页 > 解决方案 > 托管 Blazor WASM GetFromJsonAsync:无法将 JSON 值转换为 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]

我不确定这是否是我设置数据库和迁移的问题?也许它与JsonSerializerOptions我的ConfigureServices? 但如果确实如此,那么为什么我的控制器方法报告我正在取回我的对象​​列表,但我的客户端无法反序列化它?我很感激帮助/建议。谢谢

标签: c#sqliteasp.net-coreentity-framework-coreblazor-webassembly

解决方案


事实上,是的,它确实与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);
}

我从中收集到了这一点,然后我突然想到,属性名称可能由于大小写不匹配,这就是我设置PropertyNameCaseInsensitive为 true 的原因。


推荐阅读