2012-10-19 191 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() 
      } 
     }; 
    }