【发布时间】:2014-09-25 21:34:04
【问题描述】:
类似于DataTable saved to Session state loses event handlers,尽管那里推荐的解决方案不适用。我没有序列化 Session 数据。对象被保存在 InProc 中。
我有一个名为 Application 的类,其中包含以下相关位:
public class Application {
public event PropertyChangedEventHandler PropertyChanged;
private Lazy<Asset> _asset;
public String AssetId { get; set; }
public Application() {
RestoreEventHandlers(new StreamingContext());
}
[OnDeserialized]
public void RestoreEventHandlers(StreamingContext context) {
PropertyChanged += AssetId_PropertyChanged;
PropertyChanged.Invoke(this, new PropertyChangedEventArgs("AssetId"));
}
private void AssetId_PropertyChanged(Object sender, PropertyChangedEventArgs e) {
if (e.PropertyName == "AssetId")
_asset = new Lazy<Asset>(() => new Asset(AssetId));
}
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] String propertyName = null) {
var handler = PropertyChanged;
if (handler != null)
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
目标是让_asset 在相关的AssetId 属性更改时重置。我需要保持AssetId 和Asset 记录同步。我已验证该事件是在第一次创建对象后调用的。
创建应用程序后,我将其放入 Session 中,如下所示:
HttpContext.Current.Session["CurrentApplication"] = application;
在随后的请求中,我从 Session 中得到它,如下所示:
var application = HttpContext.Current.Session["CurrentApplication"] as Application;
这是从帮助类调用的,这就是为什么我需要使用静态对象来获取当前请求上下文。
稍后,如果用户要求更改应用程序上的资产,我将在同一方法中执行此操作:
application.AssetId = assetId;
在此分配之后,不会调用事件处理程序。如果我这样写,它会按预期工作:
application.RestoreEventHandlers(new StreamingContext());
application.AssetId = assetId;
某事导致我的事件处理程序变得未绑定。有什么想法吗?
【问题讨论】:
-
最后2个sn-ps的code是一样的,是不是要在最后一个里面放点别的东西?
-
@Rhumborl 是的,很好。对于那个很抱歉。我的意思是,如果我没有明确调用
RestoreEventHandlers,那么该事件将不会触发。我不想明确地调用它,因为重点是让客户端代码完全不知道该机制。
标签: c# asp.net-mvc session events