5

.NET 3.5 SP1 の変更点に関する投稿はかなりの数見てきましたが、昨日のドキュメントをまだ見ていない投稿に出くわしました。私のマシンでは、VS、msbuild コマンド ライン、すべてから正常に動作するコードがありましたが、ビルド サーバー (.NET 3.5 RTM を実行) では失敗しました。

[XmlRoot("foo")]
public class Foo
{
    static void Main()
    {
        XmlSerializer serializer = new XmlSerializer(typeof(Foo));

        string xml = @"<foo name='ack' />";
        using (StringReader sr = new StringReader(xml))
        {
            Foo foo = serializer.Deserialize(sr) as Foo;
        }
    }

    [XmlAttribute("name")]
    public string Name { get; set; }

    public Foo Bar { get; private set; }
}

SP1 では、上記のコードは問題なく動作します。RTM では、InvalidOperationException が発生します。

一時クラスを生成できません (結果 = 1)。エラー CS0200: プロパティまたはインデクサー 'ConsoleApplication2.Foo.Bar' を割り当てることができません -- 読み取り専用です

もちろん、RTM で実行するために必要なのは、[XmlIgnore] を Bar プロパティに追加することだけです。

私のGoogle fuは、これらの種類の変更のドキュメントを見つけることができないようです。この変更をリストする変更リストはどこにありますか (および、ジャンプして「落とした」と叫ぶ可能性のある同様のボンネットの下の変更)? これはバグですか、それとも機能ですか?

EDIT : SP1 では、<Bar />要素を追加するか、Bar プロパティに [XmlElement] を設定すると、逆シリアル化されません。SP1 より前のバージョンでは、デシリアライズを試行しても失敗しません。XmlSerializer の構築時に例外がスローされます。

これにより、特に Foo.Bar に [XmlElement] 属性を設定した場合は、バグである可能性が高くなります。私が要求したことを実行できない場合は、Foo.Bar を黙って無視するのではなく、例外をスローする必要があります。XML シリアライゼーション属性のその他の無効な組み合わせ/設定は、例外になります。

編集: ありがとう、TonyB、一時ファイルの場所の設定について知りませんでした。今後同様の問題が発生する場合は、追加の構成フラグが必要です。

<system.diagnostics>
  <switches>
    <add name="XmlSerialization.Compilation" value="1" />
  </switches>
</system.diagnostics>
<system.xml.serialization>
  <xmlSerializer tempFilesLocation="c:\\foo"/>
</system.xml.serialization>

Bar プロパティに [XmlElement] 属性を設定しても、生成されたシリアライゼーション アセンブリではそれについて言及されていませんでした。これは、これを静かに飲み込んだエラー (別名、バグ) の領域にかなり確実に置きます。それか、設計者が、設定できないプロパティには [XmlIgnore] は不要であると判断したかのどちらかです。これは、リリース ノート、変更リスト、またはXmlIgnoreAttribute ドキュメントで確認できます。

4

2 に答える 2

4

SP1 では、foo.Bar プロパティは適切に逆シリアル化されますか?

SP1 より前では、Bar プロパティの set メソッドがプライベートであるため、オブジェクトを逆シリアル化することはできず、XmlSerializer にはその値を設定する方法がありません。SP1がどのようにそれをやってのけるのかわかりません。

これを web.config/app.config に追加してみてください

<system.xml.serialization> 
  <xmlSerializer tempFilesLocation="c:\\foo"/> 
</system.xml.serialization> 

これにより、XmlSerializer によって生成されたクラスが c:\foo に配置されるため、SP1 と RTM での動作を確認できます。

于 2008-08-29T20:20:59.180 に答える
0

私はこの新しい (?) 動作が気に入っています。なぜなら、XML ドキュメントには Bar についての言及がなく、デシリアライザーは Bar を設定しようとしてさえいないからです。

于 2008-08-29T21:41:26.503 に答える