【问题标题】:Mapping JSON with date in object name to C# object将对象名称中带有日期的 JSON 映射到 C# 对象
【发布时间】:2019-11-25 07:09:05
【问题描述】:

我有这样的 JSON

    {
    "rates": {
        "2018-05-04": {
            "USD": 0.2813388807,
            "GBP": 0.2074019228
        },
        "2018-08-27": {
            "USD": 0.2723718099,
            "GBP": 0.2115780848
        }
        ...etc etc
    },
    "start_at": "2018-01-01",
    "base": "PLN",
    "end_at": "2018-09-01"
    }

我想将它映射到 C# 对象。我尝试使用json@csharp,但它给了我类似的东西

public class __invalid_type__20180504
{
    public double USD { get; set; }
    public double GBP { get; set; }
}

public class __invalid_type__20180827
{
    public double USD { get; set; }
    public double GBP { get; set; }
}

public class Rates
{
    public __invalid_type__20180504 __invalid_name__2018-05-04 { get; set; }
    public __invalid_type__20180827 __invalid_name__2018-08-27 { get; set; }
}

public class RootObject
{
    public Rates rates { get; set; }
    public string start_at { get; set; }
    public string @base { get; set; }
    public string end_at { get; set; }
}

我不想有像“__invalid_type__xxxxxxxx”这样的类名,我正在寻找一种将它映射到一个类的方法,以便我有一个类类型的列表。我正在使用DataContractJsonSerializerSystem.Net.Http.HttpClient

【问题讨论】:

  • json 无效 - 您需要日期的属性名称
  • 因为它不知道“2018-05-04”和“2018-08-27”是什么,只需要调整你的class rate yo list of subclass(包含美元和英镑值)
  • @Jazb 我从这里得到了 json link
  • @stefammierz 请检查我的答案。
  • 链接给出的 json 无效

标签: c# .net json rest


【解决方案1】:

您实际上不需要使用工具来为上面提到的 json 生成类。你可以有一个这样的根对象。

public class RootObject
{
    public Dictionary<string,Rate> rates { get; set; }
    public string start_at { get; set; }
    public string @base { get; set; }
    public string end_at { get; set; }
}

由于您的属性名称与费率相同,您可以使用它来定义费率对象。

public class Rate
{
    public double USD { get; set; }
    public double GBP { get; set; }
}

由于@stefammierz 在评论中提到他正在使用DataContractJsonSerializer,因此需要一个技巧才能使其反序列化为字典,如下所示:

var settings = new DataContractJsonSerializerSettings {UseSimpleDictionaryFormat = true};
var serializer = new DataContractJsonSerializer(typeof(RootObject),settings);

【讨论】:

  • 根对象是映射,但是rates字典是空的
  • @stefammierz 完美运行,但这不是答案?
  • 我检查了它作为答案
  • 还有一个问题:有没有办法让“Rate”类中的货币列表可变?例如一次只有 gpb,其他时候是 usd、eur 等
  • 您可以让您的 Rate 类包含所有货币。并将它们定义为可为空的。所以只有 json 中定义的那些会被映射。
【解决方案2】:

当 JSON 字段名称是动态的时,即日期

您可以使用JsonExtensionData,您的数据将生成键:值对

所以你的课程看起来像这样

        public class RootObject
        {
            public Rates rates { get; set; }
            public string start_at { get; set; }
            public string @base { get; set; }
            public string end_at { get; set; }
        }

        public class Rates
        {
            [JsonExtensionData]
            public Dictionary<string, JToken> Fields { get; set; }
        }

示例输出

密钥:2018-05-04

价值 - {“美元”:0.2813388807,“英镑”:0.2074019228 }

【讨论】:

    【解决方案3】:

    您可以粘贴您的 Json here 并创建类并使用 NewtonsoftJson 进行解析,

    public class RootObject
    {
        [JsonProperty("rates")]
        public Dictionary<string, Dictionary<string, double>> Rates { get; set; }
    
        [JsonProperty("start_at")]
        public DateTimeOffset StartAt { get; set; }
    
        [JsonProperty("base")]
        public string Base { get; set; }
    
        [JsonProperty("end_at")]
        public DateTimeOffset EndAt { get; set; }
    }
    

    这是迄今为止我见过的最好最快的方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-06
      • 1970-01-01
      • 1970-01-01
      • 2019-05-27
      • 2014-11-07
      • 2016-05-10
      • 2012-04-23
      • 1970-01-01
      相关资源
      最近更新 更多