繁体   English   中英

ASP.NET MVC 3 - 在重定向后获取工作流中检测当前页面是否被重定向到

[英]ASP.NET MVC 3 - Detect Whether Current Page Was Redirected To in a Post Redirect Get Workflow

在我的 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我目前的做法是设置这在我用delete控制器TempDataDeleteMyEntity方法已经成功:

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 响应代码来做到这一点,而无需使用TempData或类似机制传递此数据?

另一种方法是设置一个全局动作过滤器,为您“注入”该标志......

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 而不是傻笑。

我以类似的方式使用 TempData - 例如,在添加/更新/删除记录时显示状态消息(重定向后)我的视图。 这是 TempData 用于的那种简单的、一次性的东西,所以我说你拥有的东西是合适的。

就我个人而言,除非我绝对需要它,否则我不会弄乱 HTTP 状态代码。 您可能可以使用引用 http 标头做一些事情,但同样,这比仅使用 TempData 会更加混乱和复杂。 你有一个干净、简单的解决方案,我说你有什么就去吧。

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

由于 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");
}

基于乔治的回答:

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 的情况。

如果你打算在任何地方使用它,修改一个基本控制器可能是明智的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM