2012-04-15 3 views
2

私は、デフォルトのASP.NET Authentication controlsの動作によって、ちょっと戸惑うことがあります。ASP.NETログインコントロール、ログアウト時のページポストバックとレンダリング

私のMasterPageでは、[ログイン]または[ログアウト]リンクを表示するLoginViewコントロールを追加しました。ログインして[ログアウト]をクリックすると、アプリケーションのホームページへのリダイレクトを実行するようにコントロールを設定します。

内部的には、「ログアウト」をクリックするとポストバックが発生します。次の手順は、(もちろん他の人の間で)起こる:

ポストバックを発射したページがLoggingOutイベントが
  • LoggedOutイベント解雇され
  • リロードされるポストバックを解雇
  • ページを再初期化され
    1. ポストバックがターゲットページがロードされている
    2. リダイレクトが発生した
    3. をレンダリング済みれる解雇ページ(ロッジェを解雇されました私の場合はdOut.aspx)

    ほとんどのページで、これはうまくいきます。しかし、一部のページでは、レンダリングが正しく行われるようにデータの一部が初期化されることが予想されます。このloggoutポストバックが発生すると、データが正しく初期化されていませんが、ページがまだいくつかにつながるレンダリング済みのさ...「予期しない動作」> _を<

    私の質問は、このように二つです:

    • このレンダリングステップは、ページがまったく表示されないためになぜ発生しますか?
    • レンダリングが行われないようにする方法はありますか?

    ありがとうございました。 ティム

    PS:あなた自身のためhttp://dl.dropbox.com/u/11764136/LoginTest.7z

  • 答えて

    0

    Venemoの答えは私にはうまくいきました。

    代わりのリダイレクトを実行するためにLoginStatusコンポーネントに頼って、私はLoginStatus.LoggedOutイベントにLoginStatusコンポーネントをホストしているマスターページを登録し、リダイレクトを発射「手あたり」のPreRenderステップを呼び出すことができます前に、

    protected void Page_Load(object sender, EventArgs e) 
    { 
        MasterLoginStatus.LoggedOut += new EventHandler(OnUserLoggedOut); 
    } 
    
    private void OnUserLoggedOut(object sender, EventArgs e) 
    { 
        Response.Redirect("~/LoggedOut.aspx", true); 
    } 
    

    私はLoginStatusコンポーネントがこれを行うことにより、汚いのままかもしれない心配していたが、SOFARは、私は、例えばそれですべての問題を発見していません"実証されるまで動作する"。

    「なぜコンポーネントがこのように動作するのか」の問題が残っていますが、未解決のままになる設計上の決定だったと思います。

    編集:これは「ログイン」アクションで同じ問題が発生するまで正常に機能します。まだこの周りに道を見つけていない。

    0

    それを試してみたい場合は、ここであなたの呼び出しシーケンス&ページのライフサイクルを示す小さなVS2010のサンプルプロジェクトは、ページの実際のレンダリングを防止するための方法があります。

    ページのリダイレクト時に現在のリクエストの処理を停止します。これは、Response.Redirectメソッドにtrueパラメータを与えることによって行うことができます。

    Response.Redirect("http://somewhere", true); 
    

    ます。またResponse.Close()を呼び出すことによって、手動でこれを行うことができます。

    +0

    私はリダイレクトを実行した場合、自分はイエスが、この場合には、ログイン制御はそうFormsAuthentication.RedirectFromLoginPage()メソッドを介して私のためにそれをやっている私は、Response.Redirectを(上の一切を制御することはできません)という起こっている。 –

    +0

    おそらく、これをハックする方法がありますが、これはログイン制御がどのように機能するかです。 – Venemo

    +0

    @Tim - リダイレクトを制御できる独自の「ログイン制御」を実装しようとする可能性があります。私はあなたにそれを手伝うことができます。 – Venemo

    0

    レンダリング/再初期化する必要があるものとしないものを制御するif(!isPostBack)テストを使用していますか?

    +0

    CodeBehindではどこでも可能です。残念ながら、私のaspxページが '<%= this.CurrentProject.Note%> 'を介してクラス(ページ)プロパティにアクセスしようとすると、楽しみが始まります。 –

    +0

    '<%= this.CurrentProject.Note%>'はコードの背後にあるisPostBackによって制御されないインラインコードです...私は常にインラインではなくコード内にロジックを保持します –

    +0

    はい、そうです実際に私が元の問題を今までに回ってきた方法。しかし、私はまだそれがどうしてそんなのか不思議です。それはちょうどその直後にそれを残すためにページをレンダリングする意味がありません... –

    0

    エンドユーザーがLoginStatusコントロールのログアウトリンクをクリックしたときに、キャッシュメカニズムをバイパスしてレポート全体を要求するDevExpressコントロール(Report DocumentMap)に重大な問題があります。私は、レポートが生成されないように "ログアウト"ポストバックを止めるために多くのアプローチを試みました(いくつかのレポートはレンダリングに5分かかりました。私はこれはあなたの問題に似ていると思う:ユーザーがログアウトしている場合、重い処理をしたくない。だから私は別のアプローチを試みました:なぜ私はポストバックが確かにログアウトポストバックであることを認識していませんでしたか?すべての私のページは、ベースページから継承するので、私は基本ページにこのコードを設定しました:

    public bool IsLoggingOut { get; private set; } 
    
    protected override void OnPreInit(EventArgs e) 
    { 
        base.OnPreInit(e); 
        var eventTarget = Request.Params.Get("__EVENTTARGET"); 
        IsLoggingOut = eventTarget != null && eventTarget.Contains("HeadLoginView$HeadLoginStatus"); 
    } 
    

    今、私は私のページで行う必要があるすべてはIsLoggingOutのテストで重い処理を囲むようにあります!。 ..あなたも、あなたはちょうどこのように、任意のイベントを処理することなく、LoggedOutページにリダイレクトんでした:

    protected override void OnLoad(EventArgs e) 
    { 
        if (IsLoggingOut) 
         Response.Redirect("~/LoggedOut.aspx", true); 
    } 
    

    あなたがそのリダイレクトを行うために、イベントハンドラを使用することを好む場合でも、ということを知ることができることポストバックは本当にログアウトのクリックによるものです。

    +0

    これは私が探しているが、それは ""と等しい常にeventTargetとして動作していないようです。 – David

    +0

    @David多分あなたはポストバックを使用していないでしょう...もっと情報がなければ、なぜそれがあなたのために働いていないのかを理解するのは難しいでしょう。 – Loudenvier

    0

    私の場合、私はLoginStatusコントロールでこの問題を抱えていました。ユーザーが「ログアウト」をクリックしたときに、ページが返信され、Renderというページが表示されるのはなぜ有用なのかわかりません。いくつかのテストでは、ページ全体のライフサイクル全体を通過させなければならないことがわかったので、Reponse.End()Response.Transfer()は機能しませんでした。

    私のソリューションは、LoginStatus LoggedOutイベントのイベントハンドラを追加し、ユーザーがログアウトした場合何もしないようにマスターページにRender()メソッドをオーバーライドすることでした。私は実際にLoginStatusをマスターコントロール内にネストしていたので、そのイベントをバブリングしなければなりませんでした。

    LoginStatusコントロールを含むユーザーコントロールでは、LoggedOutイベントのイベントハンドラーを追加しました。コードビハインドで次に

    <asp:LoginStatus runat="server" ID="loginStatusDefault" OnLoggedOut="loginStatusDefault_LoggedOut" ... /> 
    

    :マスターページのデフォルトで今すぐ

    public event EventHandler LoggedOut; 
    protected void loginStatusDefault_LoggedOut(object sender, EventArgs e) 
    { 
        if (this.LoggedOut != null) 
        this.LoggedOut(sender, e); 
    } 
    

    UserStatus.aspxファイルで。

    <c:userstatus ID="ctlUserStatus" runat="server" /> 
    

    とコードビハインドで:マスター、私はすでにUSERSTATUSコントロールが含まれている私にとっては

    protected void Page_Init(object sender, EventArgs e) 
    { 
        ctlUserStatus.LoggedOut += ctlUserStatus_LoggedOut; 
    
        ... 
    } 
    
    bool IsLoggedOut { get; set; } 
    
    void ctlUserStatus_LoggedOut(object sender, EventArgs e) 
    { 
        IsLoggedOut = true; 
    } 
    
    protected override void Render(HtmlTextWriter writer) 
    { 
        if (!IsLoggedOut) 
         base.Render(writer); 
    } 
    

    を、ページのレンダリングは、ユーザーが「ログアウト」をクリックしたときに出て爆撃したもので、これはすべてのページの問題を解決しました。

    0

    私がしたことは、ログアウトリンクを持つか、またはログアウトコードを処理する "Logout.aspx"という別のページにリダイレクトするだけです。実際に素晴らしい作品。

    protected void LoginStatus1_LoggingOut(object sender, EventArgs e) 
         { 
    
          Response.Redirect("~/Logout.aspx"); 
         } 
    
    関連する問題