C# 在JSON字符串反序列化期间处理名称空间更改
我有两个应用程序在redis服务器的帮助下相互通信,在我的第一个应用程序中,我能够序列化和反序列化以下类型的对象C# 在JSON字符串反序列化期间处理名称空间更改,c#,json,redis,json.net,deserialization,C#,Json,Redis,Json.net,Deserialization,我有两个应用程序在redis服务器的帮助下相互通信,在我的第一个应用程序中,我能够序列化和反序列化以下类型的对象 { "$type": "System.Collections.Generic.Dictionary`2[[System.Int32, mscorlib], [OPCMessagingService.Resource, OPCMessagingService]], mscorlib", "71": { "$type": "OPCMessagingService.Resou
{
"$type": "System.Collections.Generic.Dictionary`2[[System.Int32, mscorlib], [OPCMessagingService.Resource, OPCMessagingService]], mscorlib",
"71": {
"$type": "OPCMessagingService.Resource, OPCMessagingService",
"SiteID": 2,
"ResourceID": 71,
"ProcessOrder": "001000380873",
"CurrentStatus": 0,
"CycleTime": 55,
"DeviceList": [
{
"$type": "OPCMessagingService.StackLight, OPCMessagingService",
"ResourceId": 71,
"DeviceIp": "10.142.117.7",
"ComPort": "COM14"
},
{
"$type": "OPCMessagingService.LED, OPCMessagingService",
"ResourceId": 71,
"DeviceIp": "10.142.117.3",
"ComPort": "COM10",
"IsMessageDelivered": false,
"RetryCount": 3,
"IsRetryRequired": true,
"_messageHeader": ":*HF601011471",
"_messageText": "DISPOMELT 5245 BULK - 0020 -投矿物油,树脂,液体树脂和橡胶",
"_delayedMessageText": "",
"_counter": 0
}
],
"UpdateDate": 20150120,
"UpdateTime": 231506,
"CurrentDate": 20150124,
"CurrentTime": 151513,
"CurrentMessage": "DISPOMELT 5245 BULK - 0020 -投矿物油,树脂,液体树脂和橡胶"
},
"72": {
"$type": "OPCMessagingService.Resource, OPCMessagingService",
"SiteID": 2,
"ResourceID": 72,
"ProcessOrder": "001000380874",
"CurrentStatus": 0,
"CycleTime": 60,
"DeviceList": [
{
"$type": "OPCMessagingService.LED, OPCMessagingService",
"ResourceId": 72,
"DeviceIp": "10.142.117.98",
"ComPort": "COM100",
"IsMessageDelivered": false,
"RetryCount": 3,
"IsRetryRequired": true,
"_messageHeader": ":*HF601011471",
"_messageText": "DISPOMELT 5245 BULK - 0050 -熔树脂",
"_delayedMessageText": "",
"_counter": 0
},
{
"$type": "OPCMessagingService.LED, OPCMessagingService",
"ResourceId": 72,
"DeviceIp": "10.142.117.4",
"ComPort": "COM11",
"IsMessageDelivered": false,
"RetryCount": 3,
"IsRetryRequired": true,
"_messageHeader": ":*HF601011471",
"_messageText": "DISPOMELT 5245 BULK - 0050 -熔树脂",
"_delayedMessageText": "",
"_counter": 0
},
{
"$type": "OPCMessagingService.StackLight, OPCMessagingService",
"ResourceId": 72,
"DeviceIp": "10.142.117.8",
"ComPort": "COM15"
},
{
"$type": "OPCMessagingService.StackLight, OPCMessagingService",
"ResourceId": 72,
"DeviceIp": "10.142.117.97",
"ComPort": "COM101"
}
],
"UpdateDate": 20150120,
"UpdateTime": 231534,
"CurrentDate": 20150124,
"CurrentTime": 151513,
"CurrentMessage": "DISPOMELT 5245 BULK - 0050 -熔树脂"
},
"73": {
"$type": "OPCMessagingService.Resource, OPCMessagingService",
"SiteID": 2,
"ResourceID": 73,
"ProcessOrder": "001000375454",
"CurrentStatus": 0,
"CycleTime": 60,
"DeviceList": [
{
"$type": "OPCMessagingService.LED, OPCMessagingService",
"ResourceId": 73,
"DeviceIp": "10.142.117.5",
"ComPort": "COM12",
"IsMessageDelivered": false,
"RetryCount": 3,
"IsRetryRequired": true,
"_messageHeader": ":*HF601011471",
"_messageText": "XHC 9228 BULK - 0050 -熔树脂",
"_delayedMessageText": "",
"_counter": 0
},
{
"$type": "OPCMessagingService.StackLight, OPCMessagingService",
"ResourceId": 73,
"DeviceIp": "10.142.117.9",
"ComPort": "COM16"
}
],
"UpdateDate": 20150120,
"UpdateTime": 223043,
"CurrentDate": 20150124,
"CurrentTime": 151513,
"CurrentMessage": "XHC 9228 BULK - 0050 -熔树脂"
},
"74": {
"$type": "OPCMessagingService.Resource, OPCMessagingService",
"SiteID": 2,
"ResourceID": 74,
"ProcessOrder": "001000375455",
"CurrentStatus": 0,
"CycleTime": 40,
"DeviceList": [
{
"$type": "OPCMessagingService.LED, OPCMessagingService",
"ResourceId": 74,
"DeviceIp": "10.142.117.2",
"ComPort": "COM9",
"IsMessageDelivered": false,
"RetryCount": 3,
"IsRetryRequired": true,
"_messageHeader": ":*HF601011471",
"_messageText": "XHC 9228 BULK - 0040 -投树脂和剩料:",
"_delayedMessageText": "",
"_counter": 0
},
{
"$type": "OPCMessagingService.StackLight, OPCMessagingService",
"ResourceId": 74,
"DeviceIp": "10.142.117.1",
"ComPort": "COM5"
}
],
"UpdateDate": 20150120,
"UpdateTime": 224143,
"CurrentDate": 20150124,
"CurrentTime": 151513,
"CurrentMessage": "XHC 9228 BULK - 0040 -投树脂和剩料:"
},
"75": {
"$type": "OPCMessagingService.Resource, OPCMessagingService",
"SiteID": 2,
"ResourceID": 75,
"ProcessOrder": "001000375456",
"CurrentStatus": 0,
"CycleTime": 50,
"DeviceList": [
{
"$type": "OPCMessagingService.StackLight, OPCMessagingService",
"ResourceId": 75,
"DeviceIp": "10.142.117.10",
"ComPort": "COM17"
},
{
"$type": "OPCMessagingService.LED, OPCMessagingService",
"ResourceId": 75,
"DeviceIp": "10.142.117.6",
"ComPort": "COM13",
"IsMessageDelivered": false,
"RetryCount": 3,
"IsRetryRequired": true,
"_messageHeader": ":*HF601011471",
"_messageText": "XHC 9228 BULK - 0020 -投矿物油和橡胶、抗氧剂,升温",
"_delayedMessageText": "",
"_counter": 0
}
],
"UpdateDate": 20150120,
"UpdateTime": 225331,
"CurrentDate": 20150124,
"CurrentTime": 151513,
"CurrentMessage": "XHC 9228 BULK - 0020 -投矿物油和橡胶、抗氧剂,升温"
}
}
我可以在一个应用程序中对其进行序列化和反序列化,但当我尝试在另一个应用程序中对其进行反序列化时,该应用程序显然具有不同的名称空间。我有个例外
解析JSON“System.Collections.Generic.Dictionary”2[[System.Int32,mscorlib],[OPCMessagingService.Resource,OPCMessagingService]],mscorlib]中指定的类型时出错。路径“$type”,第1行,位置138
在另一个应用程序中反序列化Json字符串时,我尝试了以下操作,但它不起作用。我还可以做些什么来反序列化此对象
public static T GetRedisKeyValue<T>(string key)
{
if (key.Trim().Length > 0)
{
GetSentinelMaster();
using (ConnectionMultiplexer redisClient = ConnectionMultiplexer.Connect(GetRedisConfiguraion()))
{
IDatabase redisDB = redisClient.GetDatabase(); // Getting database connection
string temp = redisDB.StringGet(key);
Type type = typeof(T);
JObject jsonObject = JObject.Parse(temp);
jsonObject["$type"] = type.FullName + ", " + type.Assembly.FullName;
// JsonConvert.DeserializeObject<T>(temp);
return JsonConvert.DeserializeObject<T>(temp, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects, TypeNameAssemblyFormat = System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full });
}
}
return default(T);
}
public static T GetRedisKeyValue(字符串键)
{
如果(键修剪().长度>0)
{
GetSentinelMaster();
使用(ConnectionMultiplexer redisClient=ConnectionMultiplexer.Connect(GetRedisConfiguration()))
{
IDatabase redisDB=redisClient.GetDatabase();//获取数据库连接
string temp=redisDB.StringGet(键);
类型=类型(T);
JObject jsonObject=JObject.Parse(temp);
jsonObject[“$type”]=type.FullName+”,“+type.Assembly.FullName;
//JsonConvert.DeserializeObject(临时);
返回JsonConvert.DeserializeObject(临时,新JsonSerializerSettings{TypeNameHandling=TypeNameHandling.Objects,TypeNameAssemblyFormat=System.Runtime.Serialization.Formatters.FormatterAssemblyStyle.Full});
}
}
返回默认值(T);
}
我还可以做些什么来实现这一点。“$type”
的格式正式包括发送系统的CLR名称空间。因此,您可以:
public class NamespaceMappingSerializationBinder : DefaultSerializationBinder
{
public string FromNamespace { get; set; }
public string ToNamespace { get; set; }
public override Type BindToType(string assemblyName, string typeName)
{
string fixedTypeName;
if (FromNamespace != null && ToNamespace != null)
{
fixedTypeName = typeName.Replace(FromNamespace, ToNamespace);
}
else
{
fixedTypeName = typeName;
}
var type = base.BindToType(assemblyName, fixedTypeName);
return type;
}
}
然后,当您反序列化JSON时,在JsonSerializerSettings
中设置Binder
,如下所示:
JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects, Binder = new NamespaceMappingSerializationBinder { FromNamespace = "From Namespace", ToNamespace = "Your Namespace" } };
上面的类型名解析非常粗糙。我在这里找到了一个更智能的解析器:。您可能还需要扩展自定义活页夹
,以拥有映射字典
类似地,如果需要在序列化时重新映射命名空间名称,并且正在.Net 4.0或更高版本中工作,您可以重写。我正在序列化和反序列化的对象类型是Dictionary Resource类型,它有一个设备列表,每个设备都是基本类型,每个设备都可以是LED或Stacklight。为什么要序列化整个命名空间?如何避免像下面这样序列化
JsonConvert.SerializeObject(值,新JsonSerializerSettings{TypeNameHandling=TypeNameHandling.Objects})
,让JSON.NET找出在另一边使用什么。我不想这样做,因为我在处理对象内的多态列表。当我不放置类信息时,它无法反序列化我的基类对象,它只是反序列化父类,而不是派生的classI能够解决问题。。我为需要序列化其数据的类创建了一个新类库,并将其添加为对我的两个应用程序的引用。这样,我在两个应用程序中都处理相同的.NET类型,它工作起来非常有魅力。