7

次の方法で .NET でオブジェクト グラフをシリアル化しようとしています。

public static byte[] Serialize(object data)
{
    var binary = new BinaryFormatter();
    using (var ms = new MemoryStream()) {
        binary.Serialize(ms, data);
        return ms.ToArray();
    }
}

ただし、次のエラーが発生しています。

FormatException: Input string was not in a correct format. 
Stack Trace: 
  at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
  at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
  at System.String.System.IConvertible.ToInt32(IFormatProvider provider)
  at System.Convert.ToInt32(Object value, IFormatProvider provider)
  at System.Runtime.Serialization.Formatters.Binary.__BinaryWriter.WriteValue(InternalPrimitiveTypeE code, Object value)
  at System.Runtime.Serialization.Formatters.Binary.__BinaryWriter.WriteMember(NameInfo memberNameInfo, NameInfo typeNameInfo, Object value)
  at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteKnownValueClass(NameInfo memberNameInfo, NameInfo typeNameInfo, Object data)
  at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMembers(NameInfo memberNameInfo, NameInfo memberTypeNameInfo, Object memberData, WriteObjectInfo objectInfo, NameInfo typeNameInfo, WriteObjectInfo memberObjectInfo)
  at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.WriteMemberSetup(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo, String memberName, Type memberType, Object memberData, WriteObjectInfo memberObjectInfo)
  at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo, String[] memberNames, Type[] memberTypes, Object[] memberData, WriteObjectInfo[] memberObjectInfos)
  at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
  at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck)
  at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck)

このエラーが発生しているフィールドを特定する簡単な方法はありますか? オブジェクト グラフのフィールドを NonSerialized として再帰的にマークして潜在的な原因を絞り込むこともできますが、オブジェクト グラフは非常に広範囲に及ぶため、これは面倒で不要に思えます。

BinaryFormatter がオブジェクト グラフ内の 1 つ以上の値をシリアル化できない理由がわからないことに注意してください。実行時にオブジェクトをメモリに格納できる場合、シリアル化できない理由は明確ではありません。これは列挙型の問題でしょうか?

4

3 に答える 3

6

Windbg を使用します。ここからダウンロードして(インストーラーからデバッガーのみを選択します。完全な SDK をダウンロードする必要はありません)、起動します。

次にFile - Open Executable- を使用して起動します。デバッガーの例外で中断します。始める前に選択しない場合

Debug - Event Filters - CLR Exception - Enabled

すべてのマネージ例外でブレークポイントを有効にします。次に、入力する必要があります

.loadby sos clr 
(if you are using .NET 3.5 .loadby sos mscorwks)
.prefer_dml 1
!dso

これにより、現在のスレッドが失敗する前に使用されたオブジェクトのリストが表示されます。次に、青い下線が引かれた NameInfo インスタンスの 1 つをクリックして、どのメンバー変数でシリアライザーが失敗したかを確認します。学ぶにはある程度の忍耐が必要であることに同意しますが、他の人が問題を解決するためにコードをいじる必要があるようなものを記録的な速さでデバッグできます。必要なのは、問題の原因となった NameInfo インスタンスを調べることだけです。

于 2012-06-12T20:27:52.627 に答える
3

私がこれにアプローチした方法は、オブジェクトを文字列にシリアル化し、その文字列をファイルに書き込むことでした。次に、シリアル化された文字列を見て、停止した場所を確認し、そこから問題の原因となった要素を推測できます。

于 2012-06-12T20:03:15.770 に答える
-1

すべてのプロパティをコメント アウトし、オブジェクトをシリアル化します。エラーが返されるまで、一度に 1 つずつ再導入します。

これは基本的なデバッグです。

ただし、シリアル化される型がそれほど多くない場合は、スタック トレースからヒントが得られます。

于 2012-06-12T20:00:09.007 に答える