gpt4 book ai didi

c# - 获取 JSON 中指定的错误解决类型

转载 作者:行者123 更新时间:2023-12-05 05:04:38 27 4
gpt4 key购买 nike

我正在使用 newtownsoft JSON,但收到以下错误:

Error resolving type specified in JSON 'CharacterData, WorldServer'. Path 'data.1.$type', line 1, position 67.

像这样反序列化时:

  JsonData receivedData = JsonConvert.DeserializeObject<JsonData>(sdata, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Objects,
TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Simple
});

强制出现此错误的 Json 部分:

{"header":"0x004","data":{"1":{"$type":"CharacterData, WorldServer","characterId":1,"connectionId":0,"accountId":3,"name":"Riorage",

这是我如何序列化它的:

string JSonData = JsonConvert.SerializeObject(SendData, Formatting.None, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto
});

我该如何修复该错误?如果在反序列化时不关心 、WorldServer,我会很棒。重要方面是 CharacterData

请注意,我在两个不同的应用程序中进行序列化和反序列化,它们通过 TCP 相互发送信息。两者都具有用于结构的完全相同的 CharacterData 类。

最佳答案

您可以使用 Custom ISerializationBinder在序列化期间指定自定义 $type 值,并在反序列化期间处理相同的自定义 $type 值。

也就是说,代替:

"$type":"CharacterData, WorldServer"

我们可以序列化为:

"$type":"CharacterData, Global"

并且可以在接收端将其转换为已知的CharacterData类型。

  • 请注意,当使用 TypeNameHandling = TypeNameHandling.Auto 时,只有当被序列化的对象的类型与其声明的类型不同时,我们的绑定(bind)器才会被调用。我想你已经是这样了,所以这方面应该没有问题。

  • 请让我提醒您,此实现必须在两端进行编码。

使概念验证符合您的情况;我临时创建了以下层次结构,其中 Transmission 是正在传输的对象。

public class Transmission
{
public TransmissionData Data { get; set; }
}

public class TransmissionData
{

}
public class CharacterData : TransmissionData
{
public string CharacterId { get; set; }
}

这是一个示例转换器:

public class CharacterDataSerializationBinder : ISerializationBinder
{
DefaultSerializationBinder defaultBinder = new DefaultSerializationBinder();

void ISerializationBinder.BindToName(Type serializedType, out string assemblyName, out string typeName)
{
if (serializedType == typeof(CharacterData))
{
assemblyName = "Global";
typeName = serializedType.Name;
}
else
{
defaultBinder.BindToName(serializedType, out assemblyName, out typeName);
}
}

Type ISerializationBinder.BindToType(string assemblyName, string typeName)
{
if (typeName == typeof(CharacterData).Name && assemblyName == "Global")
{
return typeof(CharacterData);
}
else
{
return defaultBinder.BindToType(assemblyName, typeName);
}
}
}

下面是如何使用它:

    Transmission SendData = new Transmission()
{
Data = new CharacterData() { CharacterId = "454" }
};

string JSonData = JsonConvert.SerializeObject(SendData, Formatting.None, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
SerializationBinder = new CharacterDataSerializationBinder()
});

Transmission deserializedJson = JsonConvert.DeserializeObject<Transmission>(JSonData, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
SerializationBinder = new CharacterDataSerializationBinder()
});

这是序列化输出:

{"Data":{"$type":"CharacterData, Global","CharacterId":"454"}}

希望这对您有所帮助。

更新 1:OP 询问他们是否可以使用 System.Runtime.Serialization.SerializationBinder 而不是 Json.Net 的 ISerializationBinder

答案是肯定的。 Json.Net 支持这种类型的 Binder 及其自身的 Binder 。

下面是这种 Binder 的示例实现:

public class CharacterDataCoreBinder : SerializationBinder
{
public override void BindToName(Type serializedType, out string assemblyName, out string typeName)
{
typeName = serializedType.FullName;

if (serializedType == typeof(CharacterData))
{
assemblyName = "Global";
}
else
{
assemblyName = serializedType.Assembly.GetName().Name;
}
}

public override Type BindToType(string assemblyName, string typeName)
{
if (typeName == typeof(CharacterData).FullName && assemblyName == "Global")
{
return typeof(CharacterData);
}
else
{
return Type.GetType(typeName + ", " + assemblyName);
}
}
}

下面是使用 Json.Net 序列化/反序列化时如何使用它:

    string JSonData = JsonConvert.SerializeObject(SendData, Formatting.None, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
// SerializationBinder = new CharacterDataSerializationBinder()
Binder = new CharacterDataCoreBinder()
});

Transmission deserializedJson = JsonConvert.DeserializeObject<Transmission>(JSonData, new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.Auto,
// SerializationBinder = new CharacterDataSerializationBinder()
Binder = new CharacterDataCoreBinder()
});

关于c# - 获取 JSON 中指定的错误解决类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60972554/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com