試圖創建一個服務來返回具有許多共享屬性的對象,但在某些情況下,一個屬性應該受到高度限制。這導致了奇怪的和不希望的行爲,其中在序列化輸出中重用了屬性名稱,導致瀏覽器中的行爲不正確。這是看問題,可以(如果你添加到System.Web.Extensions
參考)粘貼到LINQPad一個例子:在子類中使用「新」時,JavascriptSerializer會序列化屬性兩次
void Main()
{
System.Web.Script.Serialization.JavaScriptSerializer json = new System.Web.Script.Serialization.JavaScriptSerializer();
json.Serialize(new Full(true)).Dump();
json.Serialize(new Limited()).Dump();
}
public class Full
{
public String Stuff { get { return "Common things"; } }
public FullStatus Status { get; set; }
public Full(bool includestatus)
{
if(includestatus)
Status = new FullStatus();
}
}
public class Limited : Full
{
public new LimitedStatus Status { get; set; }
public Limited() : base(false)
{
Status = new LimitedStatus();
}
}
public class FullStatus
{
public String Text { get { return "Loads and loads and loads of things"; } }
}
public class LimitedStatus
{
public String Text { get { return "A few things"; } }
}
此打印:
{"Stuff":"Common things","Status":{"Text":"Loads and loads and loads of things"}}
{"Status":{"Text":"A few things"},"Stuff":"Common things","Status":null}
當JSON.parse是所謂的瀏覽器,第二個狀態覆蓋第一個狀態,意味着狀態始終爲空。
我可以看到解決這個唯一的辦法就是重構,使FullStatus和LimitedStatus都來自一個共同的父繼承和使用override
寧可new
- 比較複雜一點在現實世界中的代碼,但可能。我的假設是否正確?而且,我很想知道這是否是預期的行爲或錯誤。
感謝您的聯繫!我標記你的回答是正確的,因爲它是我下降的路線 - 正確地試圖迅速破解某些東西。我仍然對序列化行爲背後的原因感興趣,但我猜JSON是生成的是完全有效的(至少在Chrome中 - 早先的屬性被默默地忽略),這不是序列化程序中的錯誤,只是一些讓程序員在他們的模型中修復。 – Whelkaholism 2014-10-14 09:34:01
你的意思是爲什麼序列化程序在同一個對象中輸出兩個具有相同名稱的屬性?通常情況下,它不會,但是當你使用「new」關鍵字來隱藏一個屬性時,序列化程序會在它反映對象時發現兩個具有相同名稱的屬性,並且我猜測它在寫入時不會檢查這種情況JSON。在JSON的同一對象中擁有兩個具有相同名稱的屬性在技術上並不是每個[規範](http://tools.ietf.org/html/rfc7159)都是無效的,但它確實使JSON更少的可互操作性。 (續) – 2014-10-14 14:57:43
諷刺的是,包括Json.Net在內的一些解析器在反序列化過程中無法處理包含重複屬性名稱的對象。出於這個原因,創建帶有重複屬性名稱的JSON被認爲是不好的形式,並且如果可能的話最好避免。 – 2014-10-14 15:01:40