Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# ASP.NET MVC 3-检测当前页面是否在Post Redirect Get工作流中被重定向到_C#_Asp.net_Asp.net Mvc 3 - Fatal编程技术网

C# ASP.NET MVC 3-检测当前页面是否在Post Redirect Get工作流中被重定向到

C# ASP.NET MVC 3-检测当前页面是否在Post Redirect Get工作流中被重定向到,c#,asp.net,asp.net-mvc-3,C#,Asp.net,Asp.net Mvc 3,在我的C#.NET 4 MVC 3应用程序中,我有一个用于一组CRUD页面的删除控制器,它在成功删除后使用Post Redirect Get模式重定向到索引控制器。我只想在索引页上呈现一个按钮,如果这个页面没有被这样的操作重定向到。是否有一种简单的方法可以检测当前页面是否被重定向到(即,通过PRG重定向到达) 阅读后,我当前的方法是在deleteMeyEntity方法成功后,使用TempData在我的delete控制器中设置此选项: try { MyService.DeleteMyEnt

在我的C#.NET 4 MVC 3应用程序中,我有一个用于一组CRUD页面的删除控制器,它在成功删除后使用Post Redirect Get模式重定向到索引控制器。我只想在索引页上呈现一个按钮,如果这个页面没有被这样的操作重定向到。是否有一种简单的方法可以检测当前页面是否被重定向到(即,通过PRG重定向到达)

阅读后,我当前的方法是在
deleteMeyEntity
方法成功后,使用
TempData
在我的delete控制器中设置此选项:

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
或类似机制传递此数据?

由于3xx重定向或直接的用户启动GET,无法区分请求之间的差异。最好的方法是提供一个querystring参数,该参数仅由初始POST请求的重定向附加,但是没有任何东西可以阻止用户使用相同的querystring重新加载页面

嗯,或者您可以从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");
}

我不知道有什么更简单的机制,并且已经使用TempData很长一段时间来实现Post-Redirect-Get特性。据我所知,这正是TempData存在的原因之一。我会继续使用它。

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


就我个人而言,除非我绝对需要HTTP状态码,否则我不会弄乱它。您可能可以使用refererHTTP头来做一些事情,但同样,这比仅仅使用TempData要复杂得多。你有一个干净、简单的解决方案,可以工作,我说,按照你现有的去做。

另一个方法是设置一个全局actionfilter,为你“注入”这个标志

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(“索引”),然后签入接收处理程序


旁注:我要求你大声说,不要傻笑。

根据乔治的回答:

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
将不返回true

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


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

你可以从
HttpContext.Current.Request.Headers
中读取
referer
头的值,但这取决于客户端浏览器的性能
TempData
基本上就是为这类事情设计的,听起来像是你最好的选择。萨甘特我应该对环境有很好的控制。我看了一下这个,我想不出一个实现,在这个实现中我不需要检查一个referer是否在我不想为其呈现按钮的referer列表中。我认为从我重定向的控制器传递标志更容易。谢谢qes。这里的另一个考虑因素是,如果它有效,使用它:DDai,我将尝试一下。谢谢霍克。我唯一关心的是,其他程序员/我未来在项目中工作的自我必须了解该约定,并且它不受ViewModel之类的东西的约束,ViewModel将为此提供合理具体的用法/智能感知提示。但它最终可能是最好的解决方案,因为我对它有很多控制权。我避免使用TempData,因为它要求用户假定客户端浏览器总是会发出后续请求。这违反了“从不信任客户”规则。@AaronNewton-True,您必须了解约定;但是再一次,您必须了解很多约定,因为MVC高度基于模式和约定(例如,您正在处理的整个PRG模式)。据我所知,这是实现这一点的一种相当普遍的方式,所以这只是工具箱中要保留的另一个惯例:)谢谢qes。我刚刚发现,您可以使用方法签名从基类重写控制器,如so
protectedoverride void OnActionExecuted(ActionExecutedContext filterContext)
。然后,我可以针对该基类中的控制器设置一个属性(例如
bool Redirected
),如果继承类中的控制器中没有设置该值(例如,在方法
Delete
中设置或针对整个控制器类设置),则在
OnActionExecuted
中引发异常。然后使用此值修改ViewModel中的属性,假设ViewModels也继承基类。请参阅和。如果我能做到这一点,我会尝试发布一个代码片段。这是我与cookie temp数据提供程序一起工作时所做的,因为它会清除重定向上的cookie,有效地使我的用例无用(PRG消息)。在提供程序中,我检查标志,然后将其删除,同时防止保存(如果这是唯一的标志)。