用.NET反序列化JSON以使用对象(非特定类型)内部字段键入
相关问题:(但这是针对JSON.NET的) 是否有标准或推荐的反序列化方法,如:用.NET反序列化JSON以使用对象(非特定类型)内部字段键入,.net,json,oop,.net,Json,Oop,相关问题:(但这是针对JSON.NET的) 是否有标准或推荐的反序列化方法,如: { "command" : "register_user", "params" : { "@c" : "register_params", "name" : "sdfsd", "email" : "sdfsd@ddkdk", "password" : "JDFffJJJd", "address" : { "postcode" : "12345",
{
"command" : "register_user",
"params" : {
"@c" : "register_params",
"name" : "sdfsd",
"email" : "sdfsd@ddkdk",
"password" : "JDFffJJJd",
"address" : {
"postcode" : "12345",
"street" : "cherry st",
"number" : "44432",
"country" : "antarctica"
}
}
}
如果我们告诉反序列化程序需要消息
类型:
class Message
{
string Command;
object[] params;
}
似乎没有一个JSON反序列化框架(或其中的文档)可以处理这种情况
对于这里的这个特定示例,隐含的用法是RPC。在我的RPC解决方案中,需要将服务器对象绑定到RPC系统,并且每个RPC方法的MethodInfo都会被缓存—因此每个参数的类型确实可以从MethodInfo输入JSON反序列化器。然而,这个问题仍然是相关的,例如,如果图形变得更深,对象更复杂,那么即使这样也不够。此外,我确信这个问题已经/将会/将会在RPC案例之外遇到。所有的答案可能都很新颖,我只会选择我认为最好的解决方案。您可以将自定义的
SerializationBinder
与JSON.NET和$type
属性结合使用
让我们举一个例子:
public class TypeNameSerializationBinder : SerializationBinder
{
public string TypeFormat { get; private set; }
public TypeNameSerializationBinder(string typeFormat)
{
TypeFormat = typeFormat;
}
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
assemblyName = null;
typeName = serializedType.Name;
}
public override Type BindToType(string assemblyName, string typeName)
{
var resolvedTypeName = string.Format(TypeFormat, typeName);
return Type.GetType(resolvedTypeName, true);
}
}
现在,假设您有以下JSON:
{
"command" : "register_user",
"params" : {
"$type" : "Person",
"name" : "sdfsd",
"email" : "sdfsd@ddkdk",
"password" : "JDFffJJJd",
"address" : {
"postcode" : "12345",
"street" : "cherry st",
"number" : "44432",
"country" : "antarctica"
}
}
}
在BarBaz
组件中有以下型号:
namespace FooBar
{
public class Person
{
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
public Address Address { get; set; }
}
public class Address
{
public string Postcode { get; set; }
public string Street { get; set; }
public string Number { get; set; }
public string Country { get; set; }
}
}
和消息
类:
public class Message
{
public string Command { get; set; }
public object Params { get; set; }
}
您可以像这样反序列化它:
var settings = new JsonSerializerSettings
{
Binder = new TypeNameSerializationBinder("FooBar.{0}, BarBaz"),
TypeNameHandling = TypeNameHandling.All
};
string json = ...
var message = JsonConvert.DeserializeObject<Message>(json, settings);
Debug.Assert(message.Params is Person);
var设置=新的JsonSerializerSettings
{
Binder=新的TypeNameSerializationBinder(“FooBar.{0},BarBaz”),
TypeNameHandling=TypeNameHandling.All
};
字符串json=。。。
var message=JsonConvert.DeserializeObject(json,设置);
Assert(message.Params是Person);