從 .NET 10 開始,XmlSerializer 的行為已變更,針對使用 ObsoleteAttribute 屬性標記的屬性,它的處理方式有所不同。 先前,標示為 的 [Obsolete] 屬性會被視為也標示為 [XmlIgnore],導致它們從 XML 序列化中排除。 此行為是無意的,已更正。
透過這項變更,標記為[Obsolete]的屬性現在預設會序列化,除非IsError屬性設定為true。 如果IsError是true,序列化器會在建立期間拋出InvalidOperationException例外。 此外,還引進了 AppContext 參數 Switch.System.Xml.IgnoreObsoleteMembers,可讓開發人員視需要還原為先前的行為。
推出的版本
.NET 10
先前的行為
在舊版 .NET 中,標示有屬性 [Obsolete] 的屬性會從 XML 序列化中排除,類似於標示為 [XmlIgnore]的屬性。 此行為是非預期的,且與屬性的 [Obsolete] 預期用途不符,即提供有關已棄用 API 的編譯時間警告。
public class Example
{
public string NormalProperty { get; set; } = "normal";
[Obsolete("This property is deprecated")]
public string ObsoleteProperty { get; set; } = "obsolete";
[XmlIgnore]
public string IgnoredProperty { get; set; } = "ignored";
}
var obj = new Example();
var serializer = new XmlSerializer(typeof(Example));
using var writer = new StringWriter();
serializer.Serialize(writer, obj);
Console.WriteLine(writer.ToString());
變更前的輸出:
<Example>
<NormalProperty>normal</NormalProperty>
</Example>
新行為
從 .NET 10 開始,預設情況下,不會再排除標記為 [Obsolete] 的屬性進行 XML 序列化。 相反:
- 如果
[Obsolete]屬性與IsError = false(預設值)一起應用,則該屬性會正常序列化。 - 如果套用了
[Obsolete]屬性與IsError = true,則在建立XmlSerializer序列化程式期間會擲回InvalidOperationException例外狀況。
使用與上一個行為一節所示的相同程式碼,變更後的輸出為:
<Example>
<NormalProperty>normal</NormalProperty>
<ObsoleteProperty>obsolete</ObsoleteProperty>
</Example>
如果套用至屬性,則 [Obsolete(IsError = true)] 會在序列化程式建立期間擲回下列例外狀況:
System.InvalidOperationException:無法序列化成員 'ObsoleteProperty',因為它標示為 ObsoleteAttribute,且 IsError 設定為 true。
備註
當資料存在於 XML 中時,標示為 [Obsolete] 的屬性一律會成功還原序列化。 儘管此變更允許 [Obsolete] 屬性進行「往返」,即從物件序列化到 XML 並再返回物件,但新的行為僅影響「往返」過程中的序列化部分(即物件到 XML)。
破壞性變更的類型
此變更為行為變更。
變更的原因
先前將視為 [Obsolete] 等同 [XmlIgnore] 的行為是無意的,與屬性的 [Obsolete] 用途不一致。 這項變更可確保僅 [Obsolete] 用於提供編譯階段警告的預期目的,而且不會影響執行階段序列化行為。 AppContext 切換功能的引進可讓開發人員在需要時選擇加入舊版行為。
建議的動作
檢查您的程式碼庫,看是否依賴於屬性被排除在 XML 序列化之外的先前行為。 如果仍需要此行為,請啟用 AppContext 參數 Switch.System.Xml.IgnoreObsoleteMembers ,如下所示:
AppContext.SetSwitch("Switch.System.Xml.IgnoreObsoleteMembers", true);
如果任何屬性標示為[Obsolete(IsError = true)]並正在序列化,請更新程式碼以移除[Obsolete]屬性或設定IsError = false,以避免執行階段例外狀況。