[英]C#: How to parse JSON enums
I have a JSON string I want to convert into one of many possible types depending on type
:我有一个 JSON 字符串我想根据
type
转换为许多可能的类型之一:
{
"type": "x",
"val": {...}
}
type
is an enum. type
是一个枚举。 val
should only match a type associated with that particular enum key. val
应该只匹配与该特定枚举键关联的类型。 All possible valid val
's will have corresponding C# classes.所有可能的有效
val
都将具有相应的 C# 类。
Is it possible to do this in one pass (instead of first parsing type
only, and then using a switch
to try and parse val
into the correct type).是否可以一次完成(而不是仅首先解析
type
,然后使用switch
尝试将val
解析为正确的类型)。
How would this be done recursively without having to hand write code to map the valid type/val combinations?这将如何以递归方式完成,而无需将有效的类型/值组合手写代码到 map? Eg if this "JSON enum" pattern was nested so the
val
object contains another type
.例如,如果这个“JSON 枚举”模式是嵌套的,那么
val
object 包含另一种type
。
Thanks谢谢
Have you tried this one?你试过这个吗? I use
Newtonsoft.Json
and it works.我使用
Newtonsoft.Json
并且它有效。 I use "X" and "Y" strings and it parse them by custom converter.我使用“X”和“Y”字符串并通过自定义转换器解析它们。
Use Polymorphism to map the dynamic values.使用多态性对 map 的动态值。
Check the sample code:检查示例代码:
public enum MyType
{
X,
Y
}
public class MyJsonWithType
{
public MyType Type { get; set; }
public IValueHeader Val { get; set; }
}
public interface IValueHeader
{
}
public class MyJsonDetail1 : IValueHeader
{
public string SomeStr { get; set; }
}
public class MyJsonDetail2 : IValueHeader
{
public int SomeInt { get; set; }
}
public class MyTypeConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(MyJsonWithType).GetTypeInfo().IsAssignableFrom(objectType.GetTypeInfo());
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.StartObject)
{
JObject item = JObject.Load(reader);
if (item["Type"] != null)
{
var myType = item["Type"].ToObject<MyType>(serializer);
if (myType == MyType.X)
{
var xObject = item["Val"].ToObject<MyJsonDetail1>(serializer);
return new MyJsonWithType
{
Type = myType,
Val = xObject
};
}
else if (myType == MyType.Y)
{
var yObject = item["Val"].ToObject<MyJsonDetail2>(serializer);
return new MyJsonWithType
{
Type = myType,
Val = yObject
};
}
}
}
return null;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
static void Main(string[] args)
{
string newJson1 = "{\"Type\":\"X\",\"Val\":{\"SomeStr\":\"Test\"}}";
MyJsonWithType newTypeX = JsonConvert.DeserializeObject<MyJsonWithType>(newJson1, new MyTypeConverter());
string newJson2 = "{\"Type\":\"Y\",\"Val\":{\"SomeInt\":5566}}";
MyJsonWithType newTypeY = JsonConvert.DeserializeObject<MyJsonWithType>(newJson2, new MyTypeConverter());
DisplayMyTypeValue(newTypeX.Val);
DisplayMyTypeValue(newTypeY.Val);
}
private static void DisplayMyTypeValue(IValueHeader val)
{
if (val is MyJsonDetail1)
{
Console.WriteLine((val as MyJsonDetail1).SomeStr);
}
else if (val is MyJsonDetail2)
{
Console.WriteLine((val as MyJsonDetail2).SomeInt);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.