2

問題は、リクエストViewState中に永続化する必要があることです。CallBack

リクエストがCallBack. したがって、それを機能させるには代替手段が必要です。

ASP.NET アプリケーションには、PageStatePersisterすべての Page State ( ViewState) をSession. このようにViewStateして、クライアントに送信/取得されることはありません (非表示フィールドはページにまだ存在しますが、値はありません)。ViewState応答でを返す必要はありません。通常の要求でCallBackを保存するメカニズムを何らかの方法で呼び出す必要があるだけです。ViewStatePostBack

次のようになります。

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();
    }
    ...
}

あなたの助けに感謝。

4

2 に答える 2

2

最後にそれを手に入れました。

つまりね。

Pageクラス ( )を逆コンパイルした後、System.Web.UIASP.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);
}

MethodLoadAllState()はページの状態をロードする役割を担い、すべての PostBack リクエストを実行します。

メソッドSaveAllState()は、ページの状態を保存する責任があります。ASP.NET は、次のコードのように実行します。

if (this.IsCallback)
{
    this.RenderCallback();
}
else
{
    ...
    this.SaveAllState();
    ...
}

これが、リクエストで myViewStateが保存されない理由です!CallBack

というわけで、ついに解決!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);
}
于 2012-10-26T16:10:19.150 に答える
0

ビューの状態は、ページの SaveState および LoadState イベントで保存およびロードできます。状態を保存するページに共通の基本クラスがあるため、次のようなことができます。

    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);
    }

別の質問は、状態をどこかに保存するのが良い設計かどうかです。

于 2012-10-24T12:37:37.283 に答える