2012-10-19 181 views
9

我在C#上使用ASP.NET MVC上的Razor。防止后退按钮

我打电话给一个外部网页来处理一张信用卡,它会返回给我。然后我显示收据。

我想阻止他们回到上一个屏幕。

我没有一个底层的cs页面,就像asp一样,因为这些都是.cshtml文件来抓取事件。

此收据页面是一个视图,所以我不能把JavaScript放在标题中,因为它会影响使用它的每个页面。

任何人都知道我在这种情况下如何防止后退按钮?

+0

这将是一段JavaScript代码来做到这一点。 C#与它没有任何关系,因为C#都是服务器端。不过,我相信你可以通过搜索Stackoverflow找到答案。 [编辑:我做了你的搜索。](http://stackoverflow.com/search?q =防止+后退+按钮+浏览器) – Gromer

+0

另外,如果您在Razor文件中使用部分,则可以从特定部分视图Razor文件的页面中注入JavaScript。查看此博客了解更多信息:http://weblogs.asp.net/scottgu/archive/2010/12/30/asp-net-mvc-3-layouts-and-sections-with-razor.aspx – Gromer

+0

Can'在浏览器上禁用脚本会忽略它? – ErocM

回答

14

一种可能性是排除您不想从客户端上缓存的页面。这可以通过设置正确的响应头来完成。以下是一个[NoCache]自定义操作过滤器示例,您可以使用它来装饰相应的控制器操作。

+0

完美!非常感谢你! – ErocM

6

首先,如果前一页面发布数据到服务器,最好以Redirect(...)成功处理后的另一个动作,以避免数据在“刷新”上重新提交。

然后也设置页面到期,所以后退按钮不起作用:

https://stackoverflow.com/a/5352953/864763

+0

谢谢你,我也检查了这个答案! – ErocM

3

你问错了问题。不要试图在客户端禁用“返回”。这将注定失败;你可能会更难,但你永远不会赢得这场斗争。相反,您应该重新编写您拥有的特定页面,使其只能处理一次信用卡。你应该(在服务器上)“记住”你已经处理了信用卡,以便如果用户返回页面重新提交,你可以给他们一个错误信息,说“你已经提交了这个信息,你不能提交这个请求两次“。

现在,有几种方法可以完成这个总体目标,有些方法比其他方法更好,但这是您需要努力实现的目标。

做到这一点的一种方法是去每一页将用户重定向到这张信用卡表格;就在提交请求之前,在该用户的会话中添加一些内容(即"pendingCreditCardSubmission" = true)一旦他们提交了该请求,就会检查该会话变量。如果确实如此,请提交请求并将其设置为false,如果该请求为false或不存在,则向用户发送错误消息。

+0

这里;有一个真正的旧答案uppie! –

1

这是我们如何做到了:

public class NoBackFilterAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     filterContext.HttpContext.Response.ExpiresAbsolute = DateTime.Now; 
     filterContext.HttpContext.Response.Expires = 0; 
     filterContext.HttpContext.Response.CacheControl = "no-cache"; 
     filterContext.HttpContext.Response.Buffer = true; 
     filterContext.HttpContext.Response.Cache.SetCacheability(HttpCacheability.NoCache); 
     filterContext.HttpContext.Response.Cache.SetExpires(DateTime.UtcNow); 
     filterContext.HttpContext.Response.Cache.SetNoStore(); 
     filterContext.HttpContext.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches); 
     if (!filterContext.HttpContext.Request.IsAjaxRequest() && filterContext.HttpContext.Request.HttpMethod != "POST" && !filterContext.Controller.ControllerContext.IsChildAction) 
     { 
      var after = filterContext.HttpContext.Request.RawUrl; 
      var session = GetSession(filterContext); 
      if (session["Current"] != null) 
      { 


       if (session["Before"] != null && session["Before"].ToString() == after) 
        filterContext.HttpContext.Response.Redirect(session["Current"].ToString()); 
       else 
       { 
        session["Before"] = session["Current"]; 
        session["Current"] = after; 
       } 
      } 
      else 
      { 
       session["Current"] = after; 
      } 
     } 
     base.OnActionExecuting(filterContext); 

    } 

    private HttpSessionStateBase GetSession(ActionExecutingContext context) 
    { 
     return context.HttpContext.Session; 
    } 

} 

在这之后,你可以实现它无论是在一般范围或控制器范围。

1

问这个问题已经很久了,但是我的修复是在WebPageController类的上面添加了[NoCache]。

[NoCache] 
public class WebPageController : Controller 
{ 
    public JsonResult JsonError(Exception exception) 
    { 
     if (exception == null) throw new ArgumentNullException("exception"); 

     Response.StatusCode = 500; 

     return new JsonResult 
     { 
      JsonRequestBehavior = JsonRequestBehavior.AllowGet, 
      Data = new 
      { 
       error = true, 
       success = false, 
       message = exception.Message, 
       detail = exception.ToString() 
      } 
     }; 
    }