4

在我的 C# .NET 4 MVC 3 应用程序中,我有一个用于一组 CRUD 页面的删除控制器,它使用Post Redirect Get模式在成功删除后重定向到索引控制器。仅当此页面未被此类操作重定向到时,我才想在索引页面上呈现一个按钮。有没有一种简单的方法来检测当前页面是否被重定向到(即作为 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
}

我看到的另一个机会是args在控制器中添加另一个项目并检查它,但在这种情况下,我不妨只使用TempData. 有没有办法在请求上使用 HTTP 响应代码来执行此操作,而无需通过 withTempData或类似机制传递此数据?

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 状态代码。并且您可能可以使用referrer http 标头做一些事情,但同样,这将比仅使用 TempData 更加混乱和复杂。你有一个干净,简单的解决方案,我说你有什么。

于 2012-11-27T22:34:45.440 回答
2

我不知道任何更简单的机制,并且已经使用 TempData 很长一段时间来实现 Post-Redirect-Get 功能。据我所知,这具体是 TempData 存在的原因之一。我会继续使用它。

于 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 RedirectToActionResult将返回 true 但context.Result is RedirectToRouteResult不会。

因此,您将需要根据您对如何重定向用户的个人品味来更改该条件。当前代码适用于 OP 的情况。

如果您要在任何地方使用它,修改基本控制器可能是明智之举。

于 2020-08-14T15:12:58.280 回答