我试图反序列化List<string>
,其实际上是List<myClass>
,其对象已被序列化。例如:
static void Main(string[] args)
{
List<MyThirdClass> myThirdClass = new List<MyThirdClass>(new[] { new MyThirdClass { RoleId = 123, RoleName = "123" }, new MyThirdClass { RoleId = 234, RoleName = "234" } });
List<MySecondSerializedClass> mySecondSerializedClass = new List<MySecondSerializedClass>();
foreach (MyThirdClass thirdClass in myThirdClass)
{
MySecondSerializedClass secondClass = new MySecondSerializedClass { Roles = new List<string>() };
foreach (MyThirdClass tClass in myThirdClass)
{
secondClass.Roles.Add(JsonConvert.SerializeObject(tClass));
}
mySecondSerializedClass.Add(secondClass);
}
MyFirstSerializedClass firstClass = new MyFirstSerializedClass
{
Id = 1,
Name = "1",
Roles = mySecondSerializedClass
};
string serializedFirstClass = JsonConvert.SerializeObject(firstClass, Formatting.Indented);
MyFirstNonSerializedClass nonSerializedFirstClass = JsonConvert.DeserializeObject<MyFirstNonSerializedClass>(serializedFirstClass);
}
public class MyFirstSerializedClass
{
public int Id { get; set; }
public string Name { get; set; }
public List<MySecondSerializedClass> Roles { get; set; }
}
public class MyFirstNonSerializedClass
{
public int Id { get; set; }
public string Name { get; set; }
public List<MySecondNonSerializedClass> Roles { get; set; }
}
public class MySecondSerializedClass
{
public List<string> Roles { get; set; }
}
public class MySecondNonSerializedClass
{
public List<MyThirdClass> Roles { get; set; }
}
public class MyThirdClass
{
public int RoleId { get; set; }
public string RoleName { get; set; }
}
serializedFirstClass
会返回这样的JSON:
{
"Id": 1,
"Name": "1",
"Roles": [
{
"Roles": [
"{\"RoleId\":123,\"RoleName\":\"123\"}",
"{\"RoleId\":234,\"RoleName\":\"234\"}"
]
},
{
"Roles": [
"{\"RoleId\":123,\"RoleName\":\"123\"}",
"{\"RoleId\":234,\"RoleName\":\"234\"}"
]
}
]
}
尝试对其进行反序列化会抛出一条带有消息的异常:
转换价值时出错&#34; {&#34; RoleId&#34;:123,&#34; RoleName&#34;:&#34; 123&#34;}&#34;输入&#39; ConsoleApplication1.Program + MyThirdClass&#39;。路径&#39;角色[0] .Roles [0]&#39;,第7行,第47位。
我做错了什么或以任何方式将MyFirstSerializedClass递归反序列化为MyFirstNonSerializedClass?
答案 0 :(得分:1)
您希望将string
反序列化为MyThirdClass
结构,这是不可能的。
他们实际上并不相同。
字符串列表将序列化为
<强> “强> \” SomeProperty \ “:\” SomePropertyValue \ “的”下,
的 “强> \” SomeProperty2 \ “:\” SomePropertyValue \ “的”强>
CustomClass列表将
“SomeProperty”: “SomePropertyValue”,
“SomeProperty2”: “SomeProperty2Value”
答案 1 :(得分:1)
序列化时,将MyThirdClass
转换为字符串。
反序列化时需要逆变换。添加从字符串到您的类型的隐式转换。
public static implicit operator MyThirdClass(string s)
{
// when serializing indented =>
// return JsonConvert.DeserializeObject<B3>(s, new JsonSerializerSettings() { Formatting = Formatting.Indented});
// otherwise
return JsonConvert.DeserializeObject<B3>(s);
}
答案 2 :(得分:1)
您可以使用一组类和一个MyThirdClass
的可选JsonConverter
来执行此操作,该MyThirdClass
将当前JSON标记读取为字符串文字,然后使用嵌套的序列化程序从JSON反序列化该字符串文字作为public class MyFirstClass
{
public int Id { get; set; }
public string Name { get; set; }
public List<MySecondClass> Roles { get; set; }
}
public class MySecondClass
{
public List<MyThirdClass> Roles { get; set; }
}
public class MyThirdClass
{
public int RoleId { get; set; }
public string RoleName { get; set; }
}
public sealed class MyThirdClassStringConverter : JsonConverter
{
readonly JsonSerializerSettings settings;
public MyThirdClassStringConverter() : this(null) { }
public MyThirdClassStringConverter(JsonSerializerSettings settings)
{
this.settings = settings;
}
JsonSerializer GetInnerSerializer()
{
var innerSerializer = JsonSerializer.CreateDefault(settings);
for (int i = innerSerializer.Converters.Count - 1; i >= 0; i--)
if (innerSerializer.Converters[i] is MyThirdClassStringConverter)
innerSerializer.Converters.RemoveAt(i);
return innerSerializer;
}
public override bool CanConvert(Type objectType)
{
return typeof(MyThirdClass).IsAssignableFrom(objectType);
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
var innerSerializer = GetInnerSerializer();
if (reader.TokenType == JsonToken.String)
{
var s = reader.Value.ToString();
using (var innerReader = new StringReader(s))
return innerSerializer.Deserialize(innerReader, objectType);
}
else
{
return innerSerializer.Deserialize(reader, objectType);
}
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var innerSerializer = GetInnerSerializer();
var sb = new StringBuilder();
using (var innerWriter = new StringWriter(sb))
innerSerializer.Serialize(innerWriter, value);
writer.WriteValue(sb.ToString());
}
}
的一个实例。如果要将类序列化或反序列化为嵌入字符串,请将转换器添加到JsonSerializerSettings.Converters;将它作为对象序列化。
因此:
var stringSettings = new JsonSerializerSettings { Converters = new[] { new MyThirdClassStringConverter() } };
// Deserialize JSON where MyThirdClass objects are embedded strings
var root = JsonConvert.DeserializeObject<MyFirstClass>(stringJson, stringSettings);
// Re-serialize to JSON where MyThirdClass objects are objects
var newNonStringJson = JsonConvert.SerializeObject(root, Formatting.Indented);
// Re-serialize to JSON where MyThirdClass objects are embedded strings
var newStringJson = JsonConvert.SerializeObject(root, Formatting.Indented, stringSettings);
然后,按如下方式使用:
MyThirdClass
请注意,转换器不应直接使用[JsonConverter(typeof(MyThirdClassStringConverter))]
应用于ReadJson()
,因为会产生无限递归。转换器的SysAllocString
方法测试当前令牌是字符串还是对象并相应地进行调整,因此它可以用于以任一格式反序列化JSON。
示例fiddle。