0

我的 JSON 字符串

{
    "account_id": "123456",
    "capabilities": [
        2,
        6,
        15,
        11
    ],
   "currency": "USD"
}

我的班级定义

public class AdAccount
{
    public long account_id { get; set; }
    public string currency { get; set; }
    public List<int> capabilities { get; set; }
}

反序列化代码:

var account = JsonConvert.DeserializeObject<Account>(data, new JsonSerializerSettings() { MissingMemberHandling = Newtonsoft.Json.MissingMemberHandling.Ignore });

这一切都很好。但是我想要的是“功能”应该是一个逗号分隔的字符串,如“2,6,15,11”。所以我尝试了

public class AdAccount
{
    public long account_id { get; set; }
    public string currency { get; set; }
    private string _capabilities;
    public string capabilities { get { return _capabilities; } set { _capabilities = String.Join(",", value); } }
}

但这会引发异常

读取字符串时出错。意外令牌:StartArray。路径“能力”,第 1 行,位置 544。

在反序列化期间可以做我想做的事吗?

谢谢。

4

4 回答 4

2

我建议您创建一个附加属性来保存显示值(您的 CSV)。此属性将是只读的,并且会在您的列表更新时自行更新/重新计算。

public class AdAccount
{
    public long account_id { get; set; }
    public string currency { get; set; }
    public List<int> capabilities { get; set; }

    public string capabilitiesDisplay
    {
        get
        {
            return string.Join(", ", capabilities);
        }
    }
}

我不确定您是否需要为 Json 解析器添加忽略以忽略该属性。

这种方法的好处是,只有在您访问该值时才会计算该值。

于 2013-08-16T16:59:55.477 回答
2

您可以创建一个自定义转换器,它可以执行从List<int>到字符串的隐式转换

var obj = JsonConvert.DeserializeObject<AdAccount>(json,new MyConverter());

.

public class MyConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(string);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (objectType == typeof(string) && reader.TokenType == JsonToken.StartArray)
        {
            List<long> nums = new List<long>();
            reader.Read();
            while (reader.TokenType != JsonToken.EndArray)
            {
                nums.Add((long)reader.Value);
                reader.Read();
            }
            return String.Join(",", nums);
        }
        return existingValue;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
}

public class AdAccount
{
    public long account_id { get; set; }
    public string currency { get; set; }
    public string capabilities { get;set; }
}
于 2013-08-16T17:04:54.093 回答
0

有一个附加属性,它是您的List<int>属性的解析版本,并将其设置在属性的设置器中List<int>

public class AdAccount
{
    public long account_id { get; set; }
    public string currency { get; set; }
    private List<int> _capabilities;
    public List<int> capabilities
    {
        get { return _capabilities; }
        set { _capabilities = value; this.ParsedCapabilities = string.Join(",", value); }
    }
    public string ParsedCapabilities { get; set; }
}
于 2015-02-04T11:43:10.810 回答
0

我建议你有两种表示:

  • “自然”表示具有List<int>
  • 已连接的“数据库”表示string

您可以轻松地从一个到另一个编写转换器,这意味着您不需要在序列化/反序列化路径本身中做任何特殊的事情。当然,代价是你最终会得到两个模型。我建议让您的绝大多数代码使用“自然”表示 - 仅使用 DB 表示作为您处理数据库时的垫脚石。

于 2013-08-17T06:38:20.913 回答