【问题标题】:Deserialize JSON file that has blocks in just one Model (class)反序列化仅在一个模型(类)中具有块的 JSON 文件
【发布时间】:2018-07-26 13:11:27
【问题描述】:

如何反序列化在单个类中包含块的 JSON 文件?有没有办法可以使用 Class 中的 JSON 注释来告知属性的父块和属性的父块是什么?

JSON 如下:

{
    "Viagem": {
        "Id": 33333,
        "NumeroAtracacao": "22/2222",
        "NumeroViagem": "02002 00303",
        "Status": "DESATRACADO",
        "Joint": "UCLA UCLA",
        "Servico": "AMERICA CENTRAL",
        "MotivoEspera": "-",
        "LiberacaoRecebimento": "21/05/2018 07:00:00",
        "Navio": {
            "Nome": "MONTE CERVANTES",
            "Armador": {
                "Id": 0,
                "CodigoGeParcei": null,
                "Nome": "ALIANCA",
                "Sigla": "ALI",
                "CnpjCpf": null,
                "Endereco": null,
                "Cep": null,
                "Site": null
            },
            "ImagemNavio": ".......",
            "Comprimento": 272.08,
            "Lloyd": 9283186,
            "CallSign": "DHTK",
            "CapacidadeTeus": 5560,
            "Shortname": "MOCER"
        },
        "ChegadaPrevista": "27/05/2018 12:00:00",
        "AtracacaoPrevista": "29/05/2018 07:00:00",
        "SaidaPrevista": "30/05/2018 19:00:00",
        "DeadLine": "25/05/2018 12:00:00"
    }
}

这是我想用来反序列化 JSON 的类:

namespace WS_SantosBrasil.Model
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    using System.Data.Entity.Spatial;

    [Table("Viagem")]
    public partial class Viagem
    {
        [Key]
        [Column(Order = 0)]
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int Id { get; set; }  

        [Key]
        [Column(Order = 1)]
        [StringLength(50)]
        public string IdCtis { get; set; }

        [StringLength(20)]
        public string NumeroAtracacao { get; set; }

        [StringLength(20)]
        public string NumeroViagem { get; set; }

        [StringLength(50)]
        public string Status { get; set; }

        [StringLength(50)]
        public string Joint { get; set; }

        [StringLength(50)]
        public string Servico { get; set; }

        [StringLength(50)]
        public string MotivoEspera { get; set; }

        [StringLength(20)]
        public string LiberacaoRecebimento { get; set; }

        [StringLength(20)]
        public string ChegadaPrevista { get; set; }

        [StringLength(20)]
        public string AtracacaoPrevista { get; set; }

        [StringLength(20)]
        public string SaidaPrevista { get; set; }

        [StringLength(20)]
        public string DeadLine { get; set; }

        [StringLength(20)]
        public string Chegada { get; set; }

        [StringLength(20)]
        public string Atracacao { get; set; }

        [StringLength(20)]
        public string Saida { get; set; }

        [StringLength(20)]
        public string InicioOperacao { get; set; }

        [StringLength(20)]
        public string FimOperacao { get; set; }

        [StringLength(50)]
        public string TipoOperacao { get; set; }

        [StringLength(20)]
        public string CodigoCodesp { get; set; }

        public decimal? CaladoAtracacao { get; set; }

        public decimal? CaladoDesatracacao { get; set; }

        [StringLength(20)]
        public string NumeroViagemImportacao { get; set; }

        [StringLength(20)]
        public string NumeroViagemExportacao { get; set; }

        [StringLength(20)]
        public string PrevisaoDescarga { get; set; }

        [StringLength(20)]
        public string PrevisaoEmbarque { get; set; }

        [StringLength(20)]
        public string PrevisaoRemocao { get; set; }

        [StringLength(50)]
        public string LocalAtracacao { get; set; }

        [StringLength(100)]
        public string Navio_Nome { get; set; }

        public string ImagemNavio { get; set; }

        public decimal? Navio_Comprimento { get; set; }

        [StringLength(20)]
        public string Navio_Lloyd { get; set; }

        [StringLength(50)]
        public string Navio_CallSign { get; set; }

        public int? Navio_CapacidadeTeus { get; set; }

        [StringLength(20)]
        public string Navio_Shortname { get; set; }

        public int? Armador_Id { get; set; }

        [StringLength(20)]
        public string Armador_CodigoGeParcei { get; set; }

        [StringLength(100)]
        public string Armador_Nome { get; set; }

        [StringLength(10)]
        public string Armador_Sigla { get; set; }

        [StringLength(20)]
        public string Armador_CnpjCpf { get; set; }

        [StringLength(100)]
        public string Armador_Endereco { get; set; }

        [StringLength(20)]
        public string Armador_Cep { get; set; }

        [StringLength(100)]
        public string Armador_Site { get; set; }

        public virtual ContainerViagem ContainerViagem { get; set; }
    }
}

在反序列化该类的 JSON 时,我如何告知例如属性 Nome_Navio 位于块 Navio 内并且 JSON 属性为 NOME?

【问题讨论】:

  • 把它包在另一个类中,例如:public class Wrapper { public Viagem Viagem { get; set; }}
  • 正如其他人所说,在将信息放入 Viagem 类之前,您可能希望将 JSON 字符串反序列化为适当的类。有什么阻止你这样做吗? Visual Studio 可以从您的 JSON 文件中自动生成所需的类(复制 JSON 内容并进行编辑/特殊粘贴/“将 JSON 代码复制为类”)

标签: c# json json.net json-deserialization entity-model


【解决方案1】:

您确定不想像 CodeCaster 所说的那样创建一个类来映射它吗?

public class Viagem 
{
    public int Id {get; set;}
    public string NumeroAtracacao {get; set;}
    public string Status {get; set;}
    public string Joint {get; set;}
    public string Servico {get; set;}
    public string MotivoEspera {get; set;}
    public Navio Navio {get; set;}
    public DateTime ChegadaPrevista {get; set;}
    public DateTime AtracacaoPrevista {get; set;}
    public DateTime SaidaPrevista {get; set;}
    public DateTime DeadLine {get; set;}
}

public class Navio 
{
    public string Nome {get; set;}
    public Armador Armador {get; set;}
    public string ImagemNavio {get; set;}
    public int Comprimento {get; set;}
    public int Lloyd {get; set;}
    public string CallSign {get; set;}
    public string CapacidadeTeus {get; set}
    public string Shortname {get; set;}
}

public class Armador 
{
    public int Id {get; set;}
    public object CodigoGeParcei {get; set;}
    public string Nome {get; set;}
    public string Sigla {get; set;}
    public object CnpjCpf {get; set;}
    public object Endereco {get; set;}
    public object Cep {get; set;}
    public object Site {get; set;}
}

你可以直接做一个

JsonConvert.DersializeObject<Viagem>(json);(如果您使用的是 Newtonsoft)

【讨论】:

  • 这是我首先尝试的,但问题在于将信息保存到数据库时。那么这些类中的每一个都将是一个表,对吗?但是我必须在所有类之间建立关系,这就是做很多工作的原因。将所有信息保存到数据库的更好方法是什么。您告知的这种方式确实是反序列化的最佳方式,我面临的唯一问题是将信息保存到数据库。感谢您的帮助。
【解决方案2】:

您应该能够使用Can I specify a path in an attribute to map a property in my class to a child property in my JSON? 中的JsonPathConverter 类来做您想做的事。

要使用它,首先将[JsonConverter] 属性添加到您的Viagem 类,指定JsonPathConverter,如下所示:

[JsonConverter(typeof(JsonPathConverter))]
public partial class Viagem
{
    ...
}

然后,对于要从 JSON 反序列化的每个属性,添加一个 [JsonProperty] 属性,指定其在 JSON 中的点分隔路径。以下是几个例子:

    [JsonProperty("Viagem.Id")]
    public int Id { get; set; }

    [JsonProperty("Viagem.Status")]
    public string Status { get; set; }

    [JsonProperty("Viagem.Navio.Nome")]
    public string Navio_Nome { get; set; }

    [JsonProperty("Viagem.Navio.ImagemNavio")]
    public string ImagemNavio { get; set; }

    [JsonProperty("Viagem.Navio.Armador.Id")]
    public int? Armador_Id { get; set; }

    [JsonProperty("Viagem.Navio.Armador.Nome")]
    public string Armador_Nome { get; set; }

然后你可以像往常一样反序列化,它应该“正常工作”:

Viagem viagem = JsonConvert.DeserializeObject<Viagem>(json);

这是一个工作演示:https://dotnetfiddle.net/repgUW

请注意,如果您需要将模型序列化回 JSON,则需要在转换器中实现 WriteJson 方法。链接的问题线程中有another answer,它建议了一个实现,但我没有测试它。

【讨论】:

    【解决方案3】:

    不,您不想将 JSON 直接映射到数据库实体类。您可以不遗余力地使用do some attribute and custom serializer logic,但这是维护的噩梦(如果 JSON 或实体的结构发生变化怎么办?)。

    而是生成一个类来反序列化这个 JSON,然后将该类的字段映射到您的实体。

    【讨论】:

      猜你喜欢
      • 2012-12-03
      • 1970-01-01
      • 2023-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      • 2021-06-15
      • 2019-05-13
      相关资源
      最近更新 更多