質問

.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は、どうやらこの種の変更に関するドキュメントを見つけることができていないようです。この変更 (および、飛びついて「わかった」と叫ぶ可能性のある同様の内部的な変更) をリストした変更リストはどこかにありますか?これはバグですか、それとも機能ですか?

編集: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 ドキュメント.

役に立ちましたか?

解決

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 での動作を確認できます。

他のヒント

私はこの新しい (?) 動作がむしろ気に入っています。XML ドキュメントには Bar についての記述がないため、デシリアライザーは Bar を設定しようとする必要すらありません。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top