BlazorWebAssembly GetFromJsonAsync 未序列化子集合

hen*_*nas 0 c# .net-core blazor blazor-webassembly

问题是,为什么当我使用 HttClient .GetFromJsonAsync 从客户端调用 api 时,实体没有子集合?我从浏览器调用 api,JSON 文本有集合,但在对象上没有。

\n

这是我的实体的代码:

\n
using System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespace excelnobleza.shared.Models.Tablas.Produccion\n{\n    [Table("Lineas")]\n    public class Linea\n    {\n        public int Id { get; set; }\n        public string Nombre { get; set; }\n        public string Responsable { get; set; }\n        public string EmailResponsable { get; set; }\n        public virtual ICollection<Maquina> Maquinas { get; } = new HashSet<Maquina>();\n        public override string ToString() => this.Nombre;\n    }\n\n    public class Maquina\n    {\n        public int Id { get; set; }\n\n        [Required(ErrorMessage = "El nombre de la Maquina es requerido")]\n        public string NombreMaquina { get; set; }\n\n        [Required(ErrorMessage = "La Linea a la que pertenece la maquina es requerida")]\n        [ForeignKey("Linea")]\n        public int? Linea_Id { get; set; }\n        \n        public virtual Linea Linea { get; set; }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

我为API创建了一个控制器,返回全部的代码是:

\n
    // GET: api/Lineas\n    [HttpGet]\n    public async Task<ActionResult<Linea[]>> GetLineas()\n    {\n        return await _context.Lineas.Include(o=> o.Maquinas).ToArrayAsync();\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

这将返回 JSON,如下所示:

\n
   [\n   {\n      "Id":1,\n      "Nombre":"SCHIAVI",\n      "Responsable":"JOSUE TORRES",\n      "EmailResponsable":"jtorres",\n      "Maquinas":[\n         {\n            "Id":1,\n            "NombreMaquina":"SCHIAVI",\n            "ModeloMaquina":null,\n            "TipoMaquina_Id":1,\n            "TipoMaquina":null,\n            "Linea_Id":1\n         },\n         {\n            "Id":2,\n            "NombreMaquina":"Titan 1",\n            "ModeloMaquina":null,\n            "TipoMaquina_Id":3,\n            "TipoMaquina":null,\n            "Linea_Id":1\n         },\n         {\n            "Id":3,\n            "NombreMaquina":"Simplex",\n            "ModeloMaquina":null,\n            "TipoMaquina_Id":2,\n            "TipoMaquina":null,\n            "Linea_Id":1\n         },\n         {\n            "Id":4,\n            "NombreMaquina":"Brazile\xc3\xb1a",\n            "ModeloMaquina":null,\n            "TipoMaquina_Id":8,\n            "TipoMaquina":null,\n            "Linea_Id":1\n         }\n      ]\n   },\n   {\n      "Id":2,\n      "Nombre":"WINDMOLLER",\n      "Responsable":"ERASMO CARRASCO",\n      "EmailResponsable":"ecarrasco",\n      "Maquinas":[\n         {\n            "Id":5,\n            "NombreMaquina":"WINDMOLLER",\n            "ModeloMaquina":null,\n            "TipoMaquina_Id":1,\n            "TipoMaquina":null,\n            "Linea_Id":2\n         },\n         {\n            "Id":6,\n            "NombreMaquina":"TITAN 2",\n            "ModeloMaquina":null,\n            "TipoMaquina_Id":3,\n            "TipoMaquina":null,\n            "Linea_Id":2\n         },\n         {\n            "Id":17,\n            "NombreMaquina":"Super Simplex",\n            "ModeloMaquina":null,\n            "TipoMaquina_Id":2,\n            "TipoMaquina":null,\n            "Linea_Id":2\n         }\n      ]\n   }\n]\n
Run Code Online (Sandbox Code Playgroud)\n

RazorCode 是:

\n
@page "/lineas"\n@inject HttpClient client\n@inject IJSRuntime js\n@using excelnobleza.shared.Models.Tablas.Produccion \n\n<h3>Lineas</h3>\n<div class="form-group">\n  <a class="btn btn-success" href="lineas/create"><i class="oi oi-plus"></i> Crear</a>\n</div>\n@if (Lineas == null)\n{\n  <h3>Loading...</h3>\n}\nelse if (Lineas.Length == 0)\n{\n  <h3>No se encontraron</h3>\n}\nelse\n{\n  <table class="table table-striped">\n    <thead>\n      <tr>\n        <th>Id</th>\n        <th>Nombre</th>\n        <th>Responsable</th>\n        <th>Email Responsable</th>\n        <th></th>\n      </tr>\n    </thead>\n    <tbody>\n      @foreach (Linea lin_ in Lineas)\n      {\n        <tr>\n          <td>@lin_.Id</td>\n          <td>@lin_.Nombre</td>\n          <td>@lin_.Responsable</td>\n          <td>    \n            @foreach (Maquina maq in lin_.Maquinas)\n            {\n              <h4>@maq.NombreMaquina - @maq.ModeloMaquina</h4>\n            }\n          </td>    \n          <td>\n            <a class="btn btn-success" href="lineas/edit/@lin_.Id">Edit</a>\n          </td>\n        </tr>\n      }\n    </tbody>\n  </table>\n}\n\n@code {\n    Linea[] Lineas;    \n\n    protected override async Task OnInitializedAsync()\n    {\n      Console.WriteLine("getting Lineas...");\n      Lineas = await client.GetFromJsonAsync<Linea[]>("api/lineas");\n\n      Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(Lineas));// in this line i try to see the object string, but not have the collection\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

但“lin_”对象不显示“Maquinas”的集合。:(

\n
\n

编辑-问题已解决\n在实体上将 Icollection 更改为 List 并设置为非只读属性

\n
\n
    [Table("Lineas")]\n    public class Linea\n    {\n        public int Id { get; set; }\n        public string Nombre { get; set; }\n        public string Responsable { get; set; }\n        public string EmailResponsable { get; set; }\n        public virtual List<Maquina> Maquinas { get; set; } = new List<Maquina>();\n        public override string ToString() => this.Nombre;\n    }\n
Run Code Online (Sandbox Code Playgroud)\n

Pan*_*vos 7

该问题的原因是:

public virtual ICollection<Maquina> Maquinas { get; } = new HashSet<Maquina>();
Run Code Online (Sandbox Code Playgroud)

由于没有 setter,因此 JSON 反序列化器无法设置该属性。Maquinas是 JSON 文档中的一个数组,因此最好的类型是 a List<Maquina>

public List<Maquina> Maquinas { get;set; } 
Run Code Online (Sandbox Code Playgroud)

当需要延迟加载时,public virtual ICollection<Maquina> MaquinasEF Core 才需要签名。在这种情况下,EF Core 会生成一个代理类,仅当客户端代码尝试访问相关实体时,该类才会覆盖并加载相关实体。当前的代码急切地加载所有项目Maquinas