我的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 });
这一切都很好。然而,我想要的是"capabilities"应该是一个逗号分隔的字符串,如"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。
在反序列化过程中可以执行我想要的操作吗?
谢谢。
我建议您制作一个额外的属性来保存显示值(您的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解析器添加一个ignore来忽略该属性。
这种方法的好处是,只有当您访问该值时,才会计算该值。
您可以创建一个自定义的转换器,它可以执行从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; }
}
我建议您有两种表示:
- 具有
List<int>
的"自然"表示 - 具有联接的
string
的"数据库"表示
您可以轻松地将转换器从一个写入到另一个,这意味着您不需要在序列化/反序列化路径本身中做任何特殊的事情。当然,代价是你最终会得到两个型号。我建议让你的绝大多数代码使用"自然"表示——只使用DB表示作为处理数据库的垫脚石。
拥有一个额外的属性,该属性是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; }
}