c# - デシリアライズ・エラー。入力文字列が正しい形式でない
1. 質問です。
Nullableフィールドのデシリアライズの問題は、これまで慎重に検討されたことはなく、シリアライズとデシリアライズは同じ人またはTeamが書いた場合、問題を隠すことができるため、問題は見つかっていないようです。
コードをご覧ください。
public class A
{
public String Name { get; set; }
public decimal? Value {get; set;}
public bool ShouldSerializeValue()
{
return this.Value.HasValue;
}
}
class Program
{
static void Main(string[] args)
{
string xmlContent =
@"<A>
<Name>aa</Name>
<Value/>
</A>";
// DeserializeXML method please refer to: http://blog.csdn.net/yuxuac/article/details/16830589
A a2 = Serializer.DeserializeXML<A>(xmlContent);
Console.ReadLine();
}
}
皆さんは、このコードが正しく実行されると思いますか?
答えはノーです、エラーメッセージが出ます。入力文字列が正しい形式ではありません。
2. 原因分析。
原因は何なのか?
ShouldSerialize() メソッドから始めましょう。その役割は、そのメソッドの署名で見ることができ、特定のフィールドがシリアライズされるかどうかを制御します(もちろん、通常は、Nullable型のフィールドがシリアライズされるときに制御するために使用されます)。
次のような例を考えてみましょう。
1. Aオブジェクトを直接シリアライズする場合、意図的にValueに値を代入しない。
A a = new A(){ Name = "aa"};
string str = Util.SerializeXML(a);
XML社長はこのようになり、メソッドShouldSerializeValue()を定義します。その定義では、Valueは値がある場合のみシリアライズされると明示的に記述されているので、Valueノードはシリアライズされません:そのため
2. AからShouldSerializeValue()メソッドを削除した場合。
XML 大統領は次のようになり、Value ノードはまだ存在します(属性: xsi:nil="true" を含む)。これは ShouldSerialize メソッドを定義しない場合の既定値です。
このように、ShouldSerializeXX()の役割は、シリアライズ時に指定したフィールドをシリアライズするかどうかを制御することである。これは、ShouldSerializeとして使用されます。 XX () で、XX は定義したフィールドの名前です。
上のコードをもう一度見てみると、ShouldSerializeValue()メソッドがありますが、このメソッドはデシリアライズのときにも機能するのでしょうか?(この時点で、XMLに値のない<Value/>ノードがあります。) 私は、それがデシリアライズ時にも機能することを当然のことと思っていました。
しかし、答えはノーで、エラーが報告されます。理由は何でしょうか?
理由: デシリアライズの際、xmlContent 変数の <Value/> ノードによって定義された XML コンテンツが存在することに注意してください。 は、xsi:nil="true" でマークされていない nullable オブジェクトを認識しません。 の場合、不正な値であると判断されます。
おそらく、将来的にはShouldDeserializeXX()メソッドが追加され、この問題が解決されるでしょう。
3.ソリューション
原因が判明したが、どのように修正すればよいか?方法は2つあります。
1. Valueノードを削除する。
2. 以下のようにコードを修正することで、デシリアライズ処理を人為的に制御する(つまり、Valueフィールドの定義を修正して、Nullableオブジェクトに文字列がどのように割り当てられ、Nullableオブジェクトがどのように文字列に割り当てられるかを制御する)。
この時点で、上記のMainメソッドを実行していますが、もうエラーは報告されず、Valueの値もうまく処理されていることがわかります。
関連
-
C# string.format でのエラー: 入力文字列が正しい形式でない
-
C# indexof() の使用法
-
C#の遅延関数の使用
-
C#高精度遅延コード実行時間(us/ns)
-
C#とC++の型対応表まとめ
-
C#でUSBデバイスを操作する方法
-
Unityがエラーを報告します。コレクションが変更されました。列挙操作が実行されない可能性があります。
-
このリソースにアクセスするには完全な認証が必要です Unauthorized
-
C#のビルドコードで、すべてのコードパスが値を返さないエラーが発生する
-
System.InvalidOperationException: ConnectionString プロパティが初期化されていません。
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
C#の面接質問100選(.net開発者必見)
-
エラーです。コレクションが変更されました。列挙操作が実行されない可能性があります。
-
VS エラー LNK2005:**already defined in **.obj
-
不正なフォーマットでプログラムを読み込もうとした場合の問題を解決します。
-
エラーです。名前 'Encoding' は現在のコンテキストに存在しない ソリューション
-
C# データベース操作エラー。この接続に関連付けられた開いているDataReaderがすでにあり、これを閉じる必要があります...
-
ASP.NET URL変更によるページ受け渡し
-
C#の構文]をご覧ください。C#のリフレクション(アセンブリ)機構を説明する
-
AppDomainとAssemblyの動的なロードとアンロード
-
GDI+でジェネリックエラーが発生しました@System.Drawing.Image.RotateFlip