Json.net 反序列化字典,其中包含具有数据表值的字典
本文关键字:字典 数据表 包含具 net 反序列化 Json | 更新日期: 2023-09-27 18:36:47
我对编程相当陌生(在课堂环境之外)。
我正在开发一个带有插件的应用程序。每个插件打包/解压缩其状态(作为字典),并将自身发送到包含所有打包状态的字典中。我正在使用 Json.Net 来序列化/反序列化并将每个插件传递给它自己的类,以便根据项目是保存还是打开进行打包/解压缩。
我遇到的问题是,当我的第一个插件获取其字典版本的打包状态进行解压缩时,我开始重新填充每个属性,第一个属性(字典中的第一项)是 DataTable。我收到一条错误消息:
Unable to cast object of type 'Newtonsoft.Json.Linq.JArray' to
type 'System.Data.DataTable'.
这是我用于序列化的代码。
IDictionary<string, IDictionary<string, object>> pluginStates =
new Dictionary<string, IDictionary<string, object>>();
signaller.RaiseSaveRequest(pluginStates); //gets all of the plugins' packedState
JsonSerializer serializer = new JsonSerializer();
serializer.ObjectCreationHandling = ObjectCreationHandling.Replace;
serializer.TypeNameHandling = TypeNameHandling.All;
using (StreamWriter sw = new StreamWriter(strPathName))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, pluginStates);
}
和反序列化。
IDictionary<string, IDictionary<string, object>> pluginStates =
new Dictionary<string, IDictionary<string, object>>();
JsonSerializer serializer = new JsonSerializer();
serializer.ObjectCreationHandling = ObjectCreationHandling.Replace;
serializer.TypeNameHandling = TypeNameHandling.All;
StreamReader sr = new StreamReader(fullName);
JsonTextReader reader = new JsonTextReader(sr);
string json = sr.ReadToEnd();
pluginStates = serializer.Deserialize<IDictionary<string, IDictionary<string, Object>>>(reader);
pluginStates = JsonConvert.DeserializeObject<IDictionary<string, IDictionary<string, Object>>>(json);
sr.Close();
reader.Close();
signaller.UnpackProjectState(pluginStates);
我尝试查看NewtonSoft.Json上的文档,但我几乎不理解它以及如何使其在我的代码中工作。我想我需要对转换器或解析做一些事情,一旦插件获得其打包状态以解压缩。打包后,插件的第一个字典条目被保存为 DataTable。然后,在解包中,它是带有 : 分隔符的值中的实际数据表。
我会提供屏幕截图,但我还没有弄清楚如何做到这一点。知道我错过了什么吗?谢谢!
保存项目后,ProjMngr 会获取打包的插件状态字典。我遍历插件状态字典中的每个字典(插件),并创建一个包含键,值(json字符串版本)和键,值(.net类型)的字典。将它们添加到数组中,并将该数组放入序列化的最终 projectState 字典中。这是代码。
signaller.RaiseSaveRequest(pluginStates); <----has all plugin's packedState
//loop through plugins to get values and types
Dictionary<string, object> dictProjectState = new Dictionary<string, object>();
foreach (KeyValuePair<string,IDictionary<string,object>> plugin in pluginStates)
{
//holds jsonRepresented values
Dictionary<string, object> dictJsonRep = new Dictionary<string, object>();
//holds object types
Dictionary<string, object> dictObjRep = new Dictionary<string, object>();
object[] arrayDictHolder = new object[2]; //holds all of the dictionaries
string pluginKey = plugin.Key;
IDictionary<string, object> pluginValue = new Dictionary<string, object>();
pluginValue = plugin.Value;
foreach (KeyValuePair<string, object> element in pluginValue)
{
string jsonRepresentation = JsonConvert.SerializeObject(element.Value);
object objType = element.Value.GetType();
dictJsonRep.Add(element.Key, jsonRepresentation);
dictObjRep.Add(element.Key, objType);
}
arrayDictHolder[0] = dictJsonRep;
arrayDictHolder[1] = dictObjRep;
dictProjectState.Add(pluginKey, arrayDictHolder);
}
JsonSerializer serializer = new JsonSerializer();
using (StreamWriter sw = new StreamWriter(strPathName))
using (JsonWriter writer = new JsonTextWriter(sw))
{
serializer.Serialize(writer, dictProjectState);
}
然后,当打开一个项目时,我反向做了同样的事情,使插件状态恢复到原始状态,以发送到每个插件。使用类型来确保类型在发送之前是正确的。意识到我必须多次反序列化,这很令人惊讶。我只是无法摆脱Jarray或Jobject。但这行得通。这是我打开的方式。
IDictionary<string, IDictionary<string, object>> pluginStates = new Dictionary<string, IDictionary<string, object>>();
StreamReader sr = new StreamReader(fullName);
JsonTextReader reader = new JsonTextReader(sr);
string json = sr.ReadToEnd();
var dictProjectState = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);
sr.Close();
reader.Close();
foreach (var projectStatePair in dictProjectState)
{
string pluginKey = projectStatePair.Key; //key in pluginStates dict
Dictionary<string, object> dictJsonRep = new Dictionary<string, object>();
Dictionary<string, object> dictObjRep = new Dictionary<string, object>();
Dictionary<string, object> pluginValues = new Dictionary<string, object>();
string stpluginValue = projectStatePair.Value.ToString();
Newtonsoft.Json.Linq.JArray ja = (Newtonsoft.Json.Linq.JArray)JsonConvert.DeserializeObject(stpluginValue);
object[] arrayHolder = ja.ToObject<object[]>();
string strArray0 = arrayHolder[0].ToString();
string strArray1 = arrayHolder[1].ToString();
dictJsonRep = JsonConvert.DeserializeObject<Dictionary<string, object>>(strArray0);
dictObjRep = JsonConvert.DeserializeObject<Dictionary<string, object>>(strArray1);
foreach (var pair in dictJsonRep)
{
string strVariableKey = pair.Key;
object objType = dictObjRep[pair.Key];
string jsonRep = (string)pair.Value;
Type jsonType = Type.GetType(objType as string);
object jsonReprValue = null;
jsonReprValue = JsonConvert.DeserializeObject(jsonRep, jsonType);
pluginValues.Add(strVariableKey, jsonReprValue);
}
pluginStates.Add(pluginKey, pluginValues);
}
signaller.UnpackProjectState(pluginStates);
希望这对任何寻找答案的人都有帮助。