0

ServiceStack.Text を使用して、ネストされたクラスのリストを含むオブジェクトを逆シリアル化しようとしています。

シリアル化はうまくいきましたが、逆シリアル化しようとすると、次のエラーが発生します。

System.TypeInitializationException: 'ServiceStack.Text.Jsv.JsvReader 1' threw an exception. ---> System.TypeInitializationException: The type initializer for 'ServiceStack.Text.Jsv.JsvReader1' の型初期化子が例外をスローしました。---> System.TypeInitializationException: 'ServiceStack.Text.Common.DeserializeList 2' threw an exception. ---> System.TypeInitializationException: The type initializer for 'ServiceStack.Text.Jsv.JsvReader1' の型初期化子が例外をスローしました。---> System.TypeInitializationException: 'ServiceStack.Text.Jsv.JsvReader 1' threw an exception. ---> System.TypeInitializationException: The type initializer for 'ServiceStack.Text.Common.DeserializeList2' の型初期化子が例外をスローしました。---> System.TypeInitializationException: 'ServiceStack.Text.Jsv.JsvReader`1' の型初期化子が例外をスローしました。---> System.ArgumentException: メソッド 'Void set_Item(Int32, MyApp.MyClass)' の呼び出しに指定された引数の数が正しくありません

私のソリューションには set_Item という名前のメソッドがありません。また、ServiceStack.Text アセンブリ (リフレクターを使用) でこのような名前のメソッドを見つけることもできません。問題が何であるかはわかりません...そして、高速なシリアル化タイプが必要ですが、私が知っている最速のもの(protobuf-net)はネストされたリストをサポートしていません。

何か案は?問題の原因となったクラスは次のとおりです (protobuf メソッドをテストしたため、protomembers が存在します)。


    [Serializable]
/// <summary>
/// Description of Livres.
/// </summary>
public class Livres : IEnumerable<Livre>
{

    [ProtoMember(1)]
    private List<Livre> listeLivres;

    public List<Livre> ListeLivres
    {
        get { return listeLivres; }
        set { listeLivres = value; }
    }

    public List<string> NomLivres 
    { 
        get
        {
            List<string> lst = new List<string>();
            foreach (Livre livre in this.listeLivres) 
            {
                lst.Add(livre.NomLivre);
            }
            return lst;
        }
    }

    public int Count 
    {
        get
        {
            return ((this.listeLivres != null) ? this.listeLivres.Count : 0);
        }
    }


    public Livre this[string nomLivre]
    {
        get
        {
            nomLivre = nomLivre.ToLower();
            if (nomLivre == "") 
            {
                return null;
            }
            try 
            {
                var u = this.listeLivres.Single(book => book.NomLivre.ToLower() == nomLivre);
                return u;
            } 
            catch (InvalidOperationException)
            {
                string pattern = "^[0-9][a-zA-Z]+$";
                Regex reg = new Regex(pattern);
                if (reg.IsMatch(nomLivre)) 
                {
                    string nom = nomLivre[0].ToString() + " ";
                    nom += nomLivre.Substring(1).ToLower();
                    try 
                    {
                        var u = this.listeLivres.Single(book => book.NomLivre.ToLower() == nom);
                        return u;
                    } 
                    catch (Exception) 
                    {
                        return null;
                    }
                }
                else
                    return null;
            }
        }
        set
        {
            if (nomLivre == "") 
            {
                throw new
                    ArgumentNullException("L'index ne doit pas être une chaine vide.");
            }
            try 
            {
                Livre liv = this.listeLivres.Single(book => book.NomLivre == nomLivre);
                liv = value;
            } 
            catch (InvalidOperationException ex)
            {
                string pattern = "^[0-9][a-zA-Z]+$";
                Regex reg = new Regex(pattern);
                if (reg.IsMatch(nomLivre)) 
                {
                    string nom = nomLivre[0].ToString() + " ";
                    nom += nomLivre.Substring(1);
                    try 
                    {
                        Livre L = this.listeLivres.Single(book => book.NomLivre == nom);
                        L = value;
                    } 
                    catch (Exception e) 
                    {
                        throw new ArgumentException("Ce nom de livre n'existe pas dans la liste", e);
                    }
                }
                else
                    throw new ArgumentException("Ce nom de livre n'existe pas dans la liste", ex);
            }
        }
    }
    /// <summary>
    /// Obtient ou définit le Livre à l'index spécifié - 1
    /// Exceptions:
    /// ArgumentOutOfRangeException
    /// </summary>
    public Livre this[int index]
    {
        get
        {
            if (index < 1 || index > this.listeLivres.Count)
            {
                throw new
                    ArgumentOutOfRangeException("L'index spécifié n'était pas correct");
            }
            return this.listeLivres[index-1];

        }
        set
        {
            if (index < 1 || index > this.listeLivres.Count)
            {
                throw new
                    ArgumentOutOfRangeException("L'index spécifié n'était pas correct");
            }
            this.listeLivres[index - 1] = value;
        }
    }

    #region Constructeurs
    public Livres()
    {
        this.listeLivres = new List<Livre>();
    }
    public Livres(Livre livre)
        : this()
    {
        this.listeLivres.Add(livre);
    }

    #endregion  
    /// <summary>
    /// Retourne le verset correspondant si il existe, sinon null
    /// Exceptions
    /// ArgumentException
    /// </summary>
    /// <param name="referenceComplete">La référence du verset sous forme de chaine (ex: "1 Jean 5:19")</param>
    public Verset GetVerset(string referenceComplete)
    {
        if (string.IsNullOrWhiteSpace(referenceComplete))
            return null;
        string[] tab = referenceComplete.Split();
        try 
        {
            string livre = "";
            int chapitre;
            int verset;
            if (tab.Length>2) 
            {
                livre = tab[0];
            }
            livre += tab[tab.Length -2];
            string [] tabVerse = tab[tab.Length -1].Split(':');
            chapitre = Convert.ToInt32(tabVerse[0]);
            verset = Convert.ToInt32(tabVerse[1]);
            return this[livre][chapitre][verset];
        }
        catch (Exception ex) 
        {
            throw new ArgumentException("Il n'y a aucun verset avec cette référence",ex);
        }
    }

    public void Add(Livre livre)
    {
        this.listeLivres.Add(livre);
    }

    public static Livres operator +(Livres livres, Livre livre)
    {
        livres.Add(livre);
        return livres;
    }

    public IEnumerator<Livre> GetEnumerator()
    {
        foreach (Livre item in this.listeLivres)
        {
            yield return item;
        }
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return this.GetEnumerator();
    }


    public void Serialize(string pathName= "BibleData.txt")
    {
        try 
        {
            #region ServiceStack Serializer
            TextWriter tw = new StreamWriter(pathName);
            TypeSerializer<Livres> TypeSrlzr = new TypeSerializer<Livres>();
            TypeSrlzr.SerializeToWriter(this,tw);
            //TypeSerializer.SerializeToWriter(this,tw);
            tw.Close();
            #endregion

        }
        catch (Exception)
        {

            throw;
        }
    }

    public static Livres Deserialize(string pathName= "BibleData.txt")
    {
        try
        {
            Livres Bible;
            #region ServiceStack Deserializer
            TextReader tr = new StreamReader(pathName);

            TypeSerializer<Livres> typeSrlzr = new TypeSerializer<Livres>();
            Bible = typeSrlzr.DeserializeFromReader(tr);
            //Bible = TypeSerializer<Livres>.DeserializeFromReader(tr);
            #endregion


            return Bible;
        } 
        catch (Exception) {

            throw;
        }
    }


}
4

2 に答える 2

1

期待どおりに動作しない可能性が高いため、IEnumerable から継承したくありません。つまり、すべての Enumerable は JSON 配列/コレクションのようにシリアル化され、追加のプロパティは無視されます。

IEnumerable インターフェイスしかない場合の問題は、それを一般的に設定する方法がないことです。したがって、シリアル化はできても、逆シリアル化はできません。

IList<T>またはICollection<T > など、データを設定する機能も提供するコレクション インターフェイスを実装すると、より成功します。

于 2011-10-16T00:24:45.117 に答える
1

私も同じ問題を抱えていました。クラスで IDataErrorInfo を継承する必要がありましたが、問題はインデックス付きプロパティにあります。ただし、ソースコードで自分で修正できます。OrmLiteConfigExtensions でメソッド GetModelDefinition を見つけて、次を探します。

GetValueFn = propertyInfo.GetPropertyGetterFn()、SetValueFn = propertyInfo.GetPropertySetterFn()、

GetValueFn 行のみを次のものに置き換えます。

GetValueFn = (propertyInfo.GetIndexParameters().Length == 0)?null:propertyInfo.GetPropertyGetterFn(),

このようにして、例外をスローするインデックス付きプロパティの GetValueFn プロパティの設定をスキップします。

于 2013-08-21T01:29:20.310 に答える