我的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位。
在反序列化过程中可以做我想做的事吗?
感谢。
答案 0 :(得分: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解析器添加忽略以忽略该属性。
这种方法的好处是只有在您访问该值时才会计算该值。
答案 1 :(得分:2)
您可以创建自定义 Converter ,它可以执行从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; }
}
答案 2 :(得分:0)
我建议你有两个陈述:
List<int>
string
您可以轻松地将转换器从一个转换为另一个转换器,这意味着您无需在序列化/反序列化路径本身中执行任何特殊操作。当然,成本是你最终得到两个模型。我建议让绝大多数代码使用“自然”表示 - 只使用数据库表示作为处理数据库时的垫脚。
答案 3 :(得分:0)
有一个额外的属性,它是List<int>
属性的解析版本,并将其设置在List<int>
属性的setter中。
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; }
}