C# json.deserialize 解析一个值有时是字符串,有时是整数的 JSON。

3

我收到一系列未经标准化的JSON文件,其中一个特定字段始终是一个数字,但有时会带引号,有时不带引号。

例如:有时:

{
  "skinname": "Classic Red",
  "drivername": "",
  "country": "",
  "team": "",
  "number": "0",
  "priority": 4
}

有时候:

{
    "skinname": "Racing 125",
    "drivername": "",
    "country": "",
    "team" : "Audi Motorsport",
    "number": 125
}

最糟糕的情况:

{
  "skinname": "",
  "drivername": "",
  "country": "",
  "team": "",
  "number": "",
  "priority": 1
}

我使用 System.Text.Json.JsonSerializer.Deserialize<>() 进行反序列化到这个类:

public class JsonLiveryDetails
    {
        public string skinname { get; set; }
        public string drivername { get; set; }
        public string country { get; set; }
        public string team { get; set; }
        public string number { get; set; }
        public int? priority { get; set; }
    }

我有一个类需要反序列化,但是有时候无论我将该值分配为字符串或整数都会出现错误。

我不能在字段的get;set;中处理它,所以我通过捕获错误来解决它,尝试将其反序列化为具有其他类型的类,然后将第二个类转换为第一个类,或者捕获最终错误...

我发现我的解决方法很糟糕,也许(很可能)有更好的方法来处理它。

编辑:根据Serge的评论,添加了更多细节。 编辑2:发现另一种情况,其中数字为“”,导致建议的解决方案失败


3
你必须发布你正在使用的JSON序列化器,以及几个不同的JSON和类来反序列化。忘记Text.Json吧,改用Newtonsoft.Json,就永远不会出现任何错误了。 - Serge
请提供一个 [mcve]。 - NineBerry
请提供需要翻译的具体内容。 - alexddf
这个问题是否解决了您的疑问?System.Text.Json:使用自动转换反序列化JSON - NineBerry
2个回答

2

你可以尝试这个转换器

JsonLiveryDetails details = JsonSerializer.Deserialize<JsonLiveryDetails>(json);

public class IntToStringConverter : System.Text.Json.Serialization.JsonConverter<string>
{
    public override string Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.Number)
             return  reader.GetInt32().ToString();
      
        return reader.GetString();
    }
   
    public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
    {
        writer.WriteStringValue(value.ToString());
    }
}

public class JsonLiveryDetails
{
    public string skinname { get; set; }
    public string drivername { get; set; }
    public string country { get; set; }
    public string team { get; set; }
    [System.Text.Json.Serialization.JsonConverter(typeof(IntToStringConverter))]
    public string number { get; set; }
    public int? priority { get; set; }
}

或者将数字属性类型更改为整数可能更有意义

public class StringToIntConverter : System.Text.Json.Serialization.JsonConverter<int?>
{
    public override int? Read(ref Utf8JsonReader reader, Type type, JsonSerializerOptions options)
    {
        if (reader.TokenType == JsonTokenType.String)
        {
            var str = reader.GetString();

            if (!string.IsNullOrEmpty(str)
              && int.TryParse(str, out int val)) return val;
            else return default(int?);
        }
        return reader.GetInt32();
    }

    public override void Write(Utf8JsonWriter writer, int? value, JsonSerializerOptions options)
    {
        if (value != null)
            writer.WriteNumberValue((int)value);
            else writer.WriteNullValue();
    }
}

public class JsonLiveryDetails
{
    public string skinname { get; set; }
    public string drivername { get; set; }
    public string country { get; set; }
    public string team { get; set; }
[System.Text.Json.Serialization.JsonConverter(typeof(StringToIntConverter))]
    public int? number { get; set; }
    public int? priority { get; set; }
}

第二个在所有情况下都有效!字符串、数字和空字符串! - alexddf
不用谢!第一个也可以工作! - Serge

0

将属性声明为int,并在类或单个属性上使用JsonNumberHandling属性,以允许从字符串自动转换为整数。

[JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)]
public class JsonLiveryDetails
{
    public string skinname { get; set; }
    public string drivername { get; set; }
    public string country { get; set; }
    public string team { get; set; }
    public int number { get; set; }
    public int? priority { get; set; }
}

请参考Serge的答案,以便能够处理空字符串。

这个代码之前运行正常,直到我收到一个数值为""的JSON。 - alexddf
你想用什么值来表示空字符串? - NineBerry

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接