对象在从会话中存储/检索后正在丢失事件处理程序

本文关键字:事件处理 程序 会话 存储 对象 检索 | 更新日期: 2023-09-27 18:24:32

类似于保存到会话状态的DataTable,尽管建议的解决方案不适用,但会丢失事件处理程序。我没有序列化会话数据。对象保持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属性发生更改时重置。我需要保持AssetIdAsset记录的同步。我已经验证了事件是在第一次创建对象后调用的。

创建应用程序后,我将其放入会话中,如下所示:

HttpContext.Current.Session["CurrentApplication"] = application;

在随后的请求中,我从会话中得到它,如下所示:

var application = HttpContext.Current.Session["CurrentApplication"] as Application;

这是从助手类调用的,这就是为什么我需要使用静态对象来获取当前请求上下文。

稍后,在相同的方法中,如果用户要求更改应用程序上的资产,我有一行可以这样做:

application.AssetId = assetId;

在该赋值之后,不会调用事件处理程序。如果我用这种方式写,它会按预期工作:

application.RestoreEventHandlers(new StreamingContext());
application.AssetId = assetId;

某些原因导致我的事件处理程序未绑定。有什么想法吗?

对象在从会话中存储/检索后正在丢失事件处理程序

我可能离这里很远,但除了RestoreEventHandlers()之外,PropertyChanged事件是否被调用?我已经考虑到,您需要在属性中手动提高它-请参阅上的示例http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged(v=vs.110).aspx

private string _assetId;
public string AssetId
{
    get
    {
        return _assetId;
    }
    set
    {
        _assetId = value;
        OnPropertyChanged();
    }
}

当然,您可以在属性中重置_asset

private string _assetId;
public string AssetId
{
    get
    {
        return _assetId;
    }
    set
    {
        _assetId = value;
        _asset = new Lazy<Asset>(() => new Asset(AssetId));
    }
}