Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在回调请求时保持ViewState_C#_Asp.net_Session_Callback_Viewstate - Fatal编程技术网

C# 在回调请求时保持ViewState

C# 在回调请求时保持ViewState,c#,asp.net,session,callback,viewstate,C#,Asp.net,Session,Callback,Viewstate,问题是,我需要在回调请求期间保持ViewState 我知道,当请求是回调时,ASP.NET默认情况下不会保存页面状态。 所以,我需要一个替代方案来实现它 ASP.NET应用程序有一个自定义的PageStatePersister,它将所有页面状态(ViewState)存储到会话中。这样,ViewState在任何时候都不会发送/检索到客户端(尽管页面上仍然存在隐藏字段,但没有值)。ViewState不必在CallBack响应中返回,我只需要在正常的PostBack请求中调用保存ViewState的机

问题是,我需要在
回调
请求期间保持
ViewState

我知道,当请求是
回调时,ASP.NET默认情况下不会保存页面状态。
所以,我需要一个替代方案来实现它

ASP.NET应用程序有一个自定义的
PageStatePersister
,它将所有页面状态(
ViewState
)存储到
会话中。这样,
ViewState
在任何时候都不会发送/检索到客户端(尽管页面上仍然存在隐藏字段,但没有值)。
ViewState
不必在
CallBack
响应中返回,我只需要在正常的
PostBack
请求中调用保存
ViewState
的机制

可能是这样的:

protected void Page_LoadComplete(object sender, EventArgs e)
{
    //Set anything to the viewstate for accessing on a later postback
    ViewState["Anything"] = 1;

    if (Page.IsCallback)
    {
        //Persist the page state manualy (not needed on normal postback)
        InvokeAspNetStateSaver();
    }
    ...
}
    protected override object SaveViewState()
    {
        object state = base.SaveViewState();

        // your custom save logic
    }

    protected override void LoadViewState(object savedState)
    {
        object state = // load your view state here
        base.LoadViewState(savedState);
    }

感谢您的帮助。

可以在第页的SaveState和LoadState事件中保存和加载视图状态。由于要保存状态的页面具有公共基类,因此可以执行以下操作:

protected void Page_LoadComplete(object sender, EventArgs e)
{
    //Set anything to the viewstate for accessing on a later postback
    ViewState["Anything"] = 1;

    if (Page.IsCallback)
    {
        //Persist the page state manualy (not needed on normal postback)
        InvokeAspNetStateSaver();
    }
    ...
}
    protected override object SaveViewState()
    {
        object state = base.SaveViewState();

        // your custom save logic
    }

    protected override void LoadViewState(object savedState)
    {
        object state = // load your view state here
        base.LoadViewState(savedState);
    }
不同的问题是,将状态存储在某个地方是否是一个好的设计。

最终得到了它

事情是这样的

在对
页面
类(
System.Web.UI
)进行一些反编译之后,我基本上找到了ASP.NET在请求处理中所做的工作,包括状态加载和保存。以下代码是ASP.NET在方法
ProcessRequestMain
上执行的操作:

this.Trace.Write("aspx.page", "Begin PreInit");
this.PerformPreInit();
this.Trace.Write("aspx.page", "End PreInit");
this.Trace.Write("aspx.page", "Begin Init");
this.InitRecursive((Control) null);
this.Trace.Write("aspx.page", "End Init");
this.Trace.Write("aspx.page", "Begin InitComplete");
this.OnInitComplete(EventArgs.Empty);
this.Trace.Write("aspx.page", "End InitComplete");

if (this.IsPostBack)
{
    this.Trace.Write("aspx.page", "Begin LoadState");
    this.LoadAllState();
    this.Trace.Write("aspx.page", "End LoadState");
    this.Trace.Write("aspx.page", "Begin ProcessPostData");
    this.ProcessPostData(this._requestValueCollection, true);
    this.Trace.Write("aspx.page", "End ProcessPostData");  
}

this.Trace.Write("aspx.page", "Begin PreLoad");
this.OnPreLoad(EventArgs.Empty);
this.Trace.Write("aspx.page", "End PreLoad");
this.Trace.Write("aspx.page", "Begin Load");
this.LoadRecursive();
this.Trace.Write("aspx.page", "End Load");

if (this.IsPostBack)
{
    this.Trace.Write("aspx.page", "Begin ProcessPostData Second Try");
    this.ProcessPostData(this._leftoverPostData, false);
    this.Trace.Write("aspx.page", "End ProcessPostData Second Try");
    this.Trace.Write("aspx.page", "Begin Raise ChangedEvents");
    this.RaiseChangedEvents();
    this.Trace.Write("aspx.page", "End Raise ChangedEvents");
    this.Trace.Write("aspx.page", "Begin Raise PostBackEvent");
    this.RaisePostBackEvent(this._requestValueCollection);
    this.Trace.Write("aspx.page", "End Raise PostBackEvent");
}

this.Trace.Write("aspx.page", "Begin LoadComplete");
this.OnLoadComplete(EventArgs.Empty);
this.Trace.Write("aspx.page", "End LoadComplete");

if (this.IsPostBack && this.IsCallback)
    this.PrepareCallback(callbackControlID);
else if (!this.IsCrossPagePostBack)
{
    this.Trace.Write("aspx.page", "Begin PreRender");
    this.PreRenderRecursiveInternal();
    this.Trace.Write("aspx.page", "End PreRender");
}

...

if (this.IsCallback)
{
    this.RenderCallback();
}
else
{
    if (this.IsCrossPagePostBack)
        return;

    this.Trace.Write("aspx.page", "Begin PreRenderComplete");
    this.PerformPreRenderComplete();
    this.Trace.Write("aspx.page", "End PreRenderComplete");
    this.BuildPageProfileTree(this.EnableViewState);
    this.Trace.Write("aspx.page", "Begin SaveState");
    this.SaveAllState();
    this.Trace.Write("aspx.page", "End SaveState");
    this.Trace.Write("aspx.page", "Begin SaveStateComplete");
    this.OnSaveStateComplete(EventArgs.Empty);
    this.Trace.Write("aspx.page", "End SaveStateComplete");
    this.Trace.Write("aspx.page", "Begin Render");

    if (exportedWebPartID != null)
        this.ExportWebPart(exportedWebPartID);
    else
        this.RenderControl(this.CreateHtmlTextWriter(this.Response.Output));

    this.Trace.Write("aspx.page", "End Render");
    this.CheckRemainingAsyncTasks(false);
}
方法
LoadAllState()
负责加载页面状态,它执行每个回发请求

方法
SaveAllState()
负责保存页面状态。ASP.NET按以下代码执行:

if (this.IsCallback)
{
    this.RenderCallback();
}
else
{
    ...
    this.SaveAllState();
    ...
}
这就是我的
ViewState
无法在
回调请求中保存的原因

所以,最后,解决方案!使用反射手动调用
SaveAllState()
方法

if (Page.IsCallback)
{
    System.Reflection.MethodInfo saveAllStateMethod = typeof(System.Web.UI.Page).GetMethod("SaveAllState", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
    saveAllStateMethod.Invoke(Page, null);
}

谢谢你的回答。当.NET Framework是回调请求时,它不会保存状态。因此,不会调用SaveViewState方法(仅当它是正常回发时)。它应该是调用保存它的.NET Framework方法的某种方式。我只是不知道它到底在哪里。也许你可以在页面生命周期的某个时候,在你的回调请求中手动调用SaveViewState方法。这有点像黑客。最好使用会话或完整回发。在以后需要更改代码时,这种黑客行为可能代价高昂。