我正在尝试去除 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"}"
]
}
]
}
并试图去序列化它给消息带来了一个例外:
错误转换值" {" roalid":123," rolename":" 123"}" type'soleleapplication1.program mythirdClass'。路径'角色[0]。rol [0]',第7行,位置47。
我做错了什么,或者有任何方法将myfirstserializedClass递归归为myFirstnonSerializedClass?
您可以使用一组类和JsonConverter
的可选CC_4来完成此操作作为MyThirdClass
的实例。将转换器添加到jsonserializertings.converters时,当您要序列化或逐序将类作为嵌入式字符串化时;将其保留为序列化作为对象。
因此:
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());
}
}
然后,使用如下:
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);
请注意,将使用[JsonConverter(typeof(MyThirdClassStringConverter))]
直接将转换器应用于MyThirdClass
,因为将导致无限递归。转换器的ReadJson()
方法测试以查看当前令牌是字符串还是对象并相应地调整,因此可以以两种格式的JSON进行序列化。
示例小提琴。
您期望将string
降低到MyThirdClass
结构。
实际上它们并不相同。
字符串列表将被序列化
" " SomeProperty ":" SomePropertyValue " " ,
" " SomeProperty2 ":" SomePropertyValue " "
castulclass 的列表将为
" SomeProperty":" SomePropertyValue",
" SomeProperty2":" SomeProperty2Value"
序列化时,您将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);
}