2

私はプログラミングにかなり慣れていません (教室環境以外で)。

私はプラグインを持つアプリケーションに取り組んでいます。各プラグインは、その状態を (ディクショナリとして) パック/アンパックし、すべてのパック状態を含むディクショナリに追加するために自身を送信します。プロジェクトが保存されているか開かれているかに応じて、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 として保存されました。次に、Unpack では、値の実際の dataTable に : 区切り記号が付けられます。

スクリーンショットを提供しますが、その方法がわかりません。私が見逃しているアイデアはありますか?? ありがとう!

4

1 に答える 1

0

プロジェクトが保存されると、ProjMngr はパックされた pluginStates ディクショナリを取得します。pluginStates ディクショナリ内の各ディクショナリ (プラグイン) をループし、キー、値 (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);
}

次に、プロジェクトが開かれると、同じことを逆にして、pluginState を元の状態に戻し、各プラグインに送信しました。タイプを使用して、送信前にタイプが正しいことを確認しました。驚くべきことに、数回逆シリアル化する必要があることに気付きました。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);

これが答えを探している人に役立つことを願っています。

于 2012-06-15T19:30:41.133 に答える