簡短問題:當我在viewstate中放入同一個對象的同一個實例兩次時,在反序列化時有兩個實例。我想只有一個例子。這可以做到,怎麼樣?爲什麼ASP.NET viewstate會丟失序列化對象的身份?
羅嗦解釋:
考慮下面的代碼:
public partial class MyControl : System.Web.UI.UserControl
{
[Serializable]
class MyClass
{
public string x;
}
public void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack)
{
MyClass a = (MyClass)this.ViewState["a"];
MyClass b = (MyClass)this.ViewState["b"];
MessageManager.Show((a == b).ToString(), MessageSeverity.Debug);
}
else
{
var x = new MyClass() { x = "stackoverflow" };
this.ViewState["a"] = x;
this.ViewState["b"] = x;
MessageManager.Show("Init", MessageSeverity.Debug);
}
}
}
當它運行,並回傳被啓動時,我得到的消息, 「假」。也就是說,儘管我在視圖狀態中放置了一個對象,但它已經連續兩次了。這可以通過檢查視圖狀態內容來驗證。
如果我嘗試將交叉引用對象置於viewstate中,那麼每個項目都會被序列化爲單獨的圖形。舉例說明:
public partial class MyControl : System.Web.UI.UserControl
{
[Serializable]
class MyClass
{
public string x;
public MyClass other;
}
public void Page_Load(object sender, EventArgs e)
{
if (this.IsPostBack)
{
MyClass a = (MyClass)this.ViewState["a"];
MyClass b = (MyClass)this.ViewState["b"];
MessageManager.Show((a.other == b).ToString(), MessageSeverity.Debug);
MessageManager.Show((a.other.other == a).ToString(), MessageSeverity.Debug);
}
else
{
var a = new MyClass() { x = "stack" };
var b = new MyClass() { x = "overflow" };
a.other = b;
b.other = a;
this.ViewState["a"] = a;
this.ViewState["b"] = b;
MessageManager.Show("Init", MessageSeverity.Debug);
}
}
}
現在我得到消息「False」和「True」(按該順序)。再次,檢查Viewstate顯示,每個對象被序列化兩次。是什麼賦予了?我用ILSpy檢查了System.Web.UI.StateBag
的源碼,但它只是將所有值推入ArrayList
,並且沒有特殊的序列化代碼。所以,無論誰在序列化視圖狀態(System.Web.UI.ObjectStateFormatter
?)都以某種方式將每個對象和序列化作爲一個單獨的圖表......爲什麼?我可以解決它嗎?
更新:我需要這個的原因是相同的對象將由兩個單獨的組件持久化,並且在反序列化時,我想檢查它們是否具有相同的對象。 (或者說,它們都存儲對象集合,我需要同步這些集合)。
我可以用十幾種不同的方式實現自定義比較,但是因爲我想爲任意對象執行此操作,所以它會變得棘手。 ;)
@leppie - 那是多麼*特定*系列化工程;這並不一定適用於其他人 – 2011-05-19 09:06:53