4

私のC#.NET 4 MVC 3アプリケーションには、一連のCRUDページ用の削除コントローラーがあり、削除が成功した後、PostRedirectGetパターンを使用しインデックスコントローラーにリダイレクトします。このページがそのようなアクションによってリダイレクトされなかった場合にのみ、インデックスページにボタンをレンダリングしたいと思います。現在のページがリダイレクトされたかどうか(つまり、PRGリダイレクトの結果として到達したかどうか)を検出する簡単な方法はありますか?

http://blog.simonlovely.com/archive/2008/11/26/post-redirect-get-pattern-in-mvc.aspxを読んだ後、私の現在のアプローチは、メソッドが成功しTempDataた後に削除コントローラーでこれを設定することですDeleteMyEntity

try {
    MyService.DeleteMyEntity(MyViewModel.MyEntity);
    TempData["Redirected"] = true;
    args = new RouteValueDictionary(new { Foo = 1, Baa = 2 });
    return RedirectToAction("Index", args);
} catch (Exception e)
{
   //Logging etc. - redirect should never be reached on exception (and TempData item not set)
   throw(e);
}

次に、インデックスコントローラで、この値が存在し、真であるかどうかを確認します。

if (TempData["Redirected"] != null)
{
    //we can then do something useful with this
}

私が見るもう1つの機会は、別のアイテムを追加argsしてコントローラーでこれを確認することですが、この場合は、を使用することもできますTempDataTempDataこのデータをまたは同様のメカニズムで渡す必要なしに、リクエストでHTTP応答コードを使用してこれを行う方法はありますか?

4

5 に答える 5

5

別のルートは、そのフラグを「注入」するグローバルアクションフィルターを設定することです...

public class RedirectDetect: ActionFilterAttribute{
   public override void OnActionExecuted(ActionExecutedContext filterContext){
        if (filterContext.Result is RedirectToRouteResult ||
            filterContext.Result is RedirectResult)
        {
             TempData["Redirected"] = true;
             //or what ever other indicator you want to set
        }
   }
}

次に、redirectToAction( "Index")を呼び出して、受信ハンドラーをチェックインします。

補足:RedirectDetectを声に出して言って、笑わないように言ってください。

于 2014-03-10T18:46:07.507 に答える
3

私は同様の方法でTempDataを使用します。たとえば、レコードが追加/更新/削除されたときにビューに(リダイレクトした後の)ステータスメッセージを表示します。これは、TempDataが使用される一種の単純で使い捨てのものなので、あなたが持っているものが適切であると私は言います。

個人的には、絶対に必要でない限り、HTTPステータスコードをいじることはありません。また、リファラーhttpヘッダーを使用して何かを行うこともできますが、これも、TempDataを使用するよりもはるかに面倒で複雑になります。あなたはうまくいくクリーンでシンプルな解決策を持っています、私はあなたが持っているもので行くと言います。

于 2012-11-27T22:34:45.440 に答える
2

私はもっ​​と単純なメカニズムを認識しておらず、Post-Redirect-Get機能を実装するためにかなり長い間TempDataを使用しています。私の知る限り、これがTempDataが存在する理由の1つです。使い続けます。

于 2012-11-27T22:31:21.473 に答える
1

3xxリダイレクトまたはユーザーが開始した単純なGETの結果として、リクエストを区別する方法はありません。最良の方法は、最初のPOSTリクエストのリダイレクトによってのみ追加されるクエリ文字列引数を提供することですが、ユーザーが同じクエリ文字列でページを再読み込みすることを妨げるものは何もありません。

うーん、またはPOSTからのリダイレクトを使用してCookieを送信し、次のように後続のGETの応答でCookieを削除することができます。

public ActionResult PostHandler(ViewModel model) {
    SetCookie("redirected", "true"); // psuedocode
    return Redirect("GetHandler2");
}

public ActionResult GetHandler2() {
    if( GetCookie("redirected") == "true" ) {
        // do something
    }
    DeleteCookie("redirected");
}
于 2012-11-27T22:26:53.250 に答える
0

ジョージの答えから構築する:

public class MarkRedirects : ActionFilterAttribute
{
   public override void OnActionExecuted(ActionExecutedContext context)
   {
        if (context.Result is RedirectToActionResult ||
            context.Result is RedirectResult)
        {
            // Obtain and verify the underlying IController
            var controller = context.Controller as Controller;
            if (controller != null)
                controller.TempData["Redirected"] = true; // or set other dictionary data here
        }
   }
}

context.Resultの条件付きチェックは、リダイレクトに使用したメソッドによって異なります。たとえば、RedirectToAction()メソッドを介してユーザーをリダイレクトした場合、context.Result is RedirectToActionResulttrueが返されますが、返されcontext.Result is RedirectToRouteResultません。

このため、ユーザーをリダイレクトする方法の個人的な好みに基づいて、条件を変更する必要があります。現在のコードはOPの状況で機能します。

これをどこでも使用する場合は、ベースコントローラーを変更することをお勧めします。

于 2020-08-14T15:12:58.280 に答える