C#将Json转换为具有不同数据类型的重复属性名称的对象 [英] C# Convert Json to object with duplicated property name with different data type
问题描述
我有一个json字符串,具有重复的属性名称和不同的数据类型.如果我删除所有重复的其他数据类型,它将正常工作.
i have a json string with duplicated property name with different data types. if i removed all duplicated other data types, it will work fine.
{
"data":[
{
"ctr":0,
"spend":11839.8600,
"clicks":6402
},
{
"ctr":0,
"spend":12320.5000,
"clicks":5789
},
{
"clicks":{
"value":13156.0,
"prior_year":0.0,
"prior_month":14122.0,
"prior_month_perc":0.0684039087947882736156351792,
"prior_year_perc":0.0
}
}
],
"timing":null,
"warnings":[
],
"success":true
}
这是我的模型课
public class MyTestModel
{
public int? ctr { get; set; }
public decimal? spend { get; set; }
public int? clicks { get; set; }
}
如果我删除了这个被截断的json部分,程序将正常工作.
if i removed this snipped json part, program will work.
{
"clicks":{
"value":13156.0,
"prior_year":0.0,
"prior_month":14122.0,
"prior_month_perc":0.0684039087947882736156351792,
"prior_year_perc":0.0
}
有什么方法可以停止将不受支持的类型绑定到模型属性.
are there any method to stop binding unsupported types to model property.
推荐答案
您可以使用JsonConverter
支持联合"类中的一种/两种类型.
You can use a JsonConverter
to support either/both types in a 'union' class.
public partial class ClicksClass
{
[JsonProperty("value")]
public long Value { get; set; }
[JsonProperty("prior_year")]
public long PriorYear { get; set; }
[JsonProperty("prior_month")]
public long PriorMonth { get; set; }
[JsonProperty("prior_month_perc")]
public double PriorMonthPerc { get; set; }
[JsonProperty("prior_year_perc")]
public long PriorYearPerc { get; set; }
}
public partial struct ClicksUnion
{
public ClicksClass ClicksClass;
public long? Integer;
public static implicit operator ClicksUnion(ClicksClass ClicksClass) => new ClicksUnion { ClicksClass = ClicksClass };
public static implicit operator ClicksUnion(long Integer) => new ClicksUnion { Integer = Integer };
}
internal static class Converter
{
public static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
{
MetadataPropertyHandling = MetadataPropertyHandling.Ignore,
DateParseHandling = DateParseHandling.None,
Converters =
{
ClicksUnionConverter.Singleton,
new IsoDateTimeConverter { DateTimeStyles = DateTimeStyles.AssumeUniversal }
},
};
}
internal class ClicksUnionConverter : JsonConverter
{
public override bool CanConvert(Type t) => t == typeof(ClicksUnion) || t == typeof(ClicksUnion?);
public override object ReadJson(JsonReader reader, Type t, object existingValue, JsonSerializer serializer)
{
switch (reader.TokenType)
{
case JsonToken.Integer:
var integerValue = serializer.Deserialize<long>(reader);
return new ClicksUnion { Integer = integerValue };
case JsonToken.StartObject:
var objectValue = serializer.Deserialize<ClicksClass>(reader);
return new ClicksUnion { ClicksClass = objectValue };
}
throw new Exception("Cannot unmarshal type ClicksUnion");
}
public override void WriteJson(JsonWriter writer, object untypedValue, JsonSerializer serializer)
{
var value = (ClicksUnion)untypedValue;
if (value.Integer != null)
{
serializer.Serialize(writer, value.Integer.Value);
return;
}
if (value.ClicksClass != null)
{
serializer.Serialize(writer, value.ClicksClass);
return;
}
throw new Exception("Cannot marshal type ClicksUnion");
}
public static readonly ClicksUnionConverter Singleton = new ClicksUnionConverter();
}
这意味着,一旦解析,只要进入ClickUnion
实例,就可以检查哪个字段不为null,这就是您使用的字段.当然,这取决于您的用例.
This means that, once parsed, whenever you get to the ClickUnion
instances, you can check which field is not null, and that is the one you use. It depends on your usecase of course.
顺便说一句,我用此网站从json
BTW, I used this web site to write the classes from the json
这篇关于C#将Json转换为具有不同数据类型的重复属性名称的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!