首页 > 解决方案 > BlazorWebAssembly GetFromJsonAsync 不序列化子集合

问题描述

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

这是我的实体的代码:

using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace excelnobleza.shared.Models.Tablas.Produccion
{
    [Table("Lineas")]
    public class Linea
    {
        public int Id { get; set; }
        public string Nombre { get; set; }
        public string Responsable { get; set; }
        public string EmailResponsable { get; set; }
        public virtual ICollection<Maquina> Maquinas { get; } = new HashSet<Maquina>();
        public override string ToString() => this.Nombre;
    }

    public class Maquina
    {
        public int Id { get; set; }

        [Required(ErrorMessage = "El nombre de la Maquina es requerido")]
        public string NombreMaquina { get; set; }

        [Required(ErrorMessage = "La Linea a la que pertenece la maquina es requerida")]
        [ForeignKey("Linea")]
        public int? Linea_Id { get; set; }
        
        public virtual Linea Linea { get; set; }
    }
}

我为 API 创建了一个控制器,return all 的代码是:

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

这将返回 JSON,如:

   [
   {
      "Id":1,
      "Nombre":"SCHIAVI",
      "Responsable":"JOSUE TORRES",
      "EmailResponsable":"jtorres",
      "Maquinas":[
         {
            "Id":1,
            "NombreMaquina":"SCHIAVI",
            "ModeloMaquina":null,
            "TipoMaquina_Id":1,
            "TipoMaquina":null,
            "Linea_Id":1
         },
         {
            "Id":2,
            "NombreMaquina":"Titan 1",
            "ModeloMaquina":null,
            "TipoMaquina_Id":3,
            "TipoMaquina":null,
            "Linea_Id":1
         },
         {
            "Id":3,
            "NombreMaquina":"Simplex",
            "ModeloMaquina":null,
            "TipoMaquina_Id":2,
            "TipoMaquina":null,
            "Linea_Id":1
         },
         {
            "Id":4,
            "NombreMaquina":"Brazileña",
            "ModeloMaquina":null,
            "TipoMaquina_Id":8,
            "TipoMaquina":null,
            "Linea_Id":1
         }
      ]
   },
   {
      "Id":2,
      "Nombre":"WINDMOLLER",
      "Responsable":"ERASMO CARRASCO",
      "EmailResponsable":"ecarrasco",
      "Maquinas":[
         {
            "Id":5,
            "NombreMaquina":"WINDMOLLER",
            "ModeloMaquina":null,
            "TipoMaquina_Id":1,
            "TipoMaquina":null,
            "Linea_Id":2
         },
         {
            "Id":6,
            "NombreMaquina":"TITAN 2",
            "ModeloMaquina":null,
            "TipoMaquina_Id":3,
            "TipoMaquina":null,
            "Linea_Id":2
         },
         {
            "Id":17,
            "NombreMaquina":"Super Simplex",
            "ModeloMaquina":null,
            "TipoMaquina_Id":2,
            "TipoMaquina":null,
            "Linea_Id":2
         }
      ]
   }
]

RazorCode 是:

@page "/lineas"
@inject HttpClient client
@inject IJSRuntime js
@using excelnobleza.shared.Models.Tablas.Produccion 

<h3>Lineas</h3>
<div class="form-group">
  <a class="btn btn-success" href="lineas/create"><i class="oi oi-plus"></i> Crear</a>
</div>
@if (Lineas == null)
{
  <h3>Loading...</h3>
}
else if (Lineas.Length == 0)
{
  <h3>No se encontraron</h3>
}
else
{
  <table class="table table-striped">
    <thead>
      <tr>
        <th>Id</th>
        <th>Nombre</th>
        <th>Responsable</th>
        <th>Email Responsable</th>
        <th></th>
      </tr>
    </thead>
    <tbody>
      @foreach (Linea lin_ in Lineas)
      {
        <tr>
          <td>@lin_.Id</td>
          <td>@lin_.Nombre</td>
          <td>@lin_.Responsable</td>
          <td>    
            @foreach (Maquina maq in lin_.Maquinas)
            {
              <h4>@maq.NombreMaquina - @maq.ModeloMaquina</h4>
            }
          </td>    
          <td>
            <a class="btn btn-success" href="lineas/edit/@lin_.Id">Edit</a>
          </td>
        </tr>
      }
    </tbody>
  </table>
}

@code {
    Linea[] Lineas;    

    protected override async Task OnInitializedAsync()
    {
      Console.WriteLine("getting Lineas...");
      Lineas = await client.GetFromJsonAsync<Linea[]>("api/lineas");

      Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(Lineas));// in this line i try to see the object string, but not have the collection
    }
}

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

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

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

标签: c#.net-coreblazorblazor-webassembly

解决方案


问题是由以下原因引起的:

public virtual ICollection<Maquina> Maquinas { get; } = new HashSet<Maquina>();

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

public List<Maquina> Maquinas { get;set; } 

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


推荐阅读