2012-10-19 14 views
9

Sto usando Razor su ASP.NET MVC con C#.Prevent back button

Sto chiamando una pagina Web esterna per elaborare una carta di credito e restituisce a me. Quindi visualizzo una ricevuta.

Mi piacerebbe impedire loro di tornare alla schermata precedente.

Non ho una pagina cs sottostante, come asp poiché questi sono file .cshtml, per afferrare l'evento.

Questa pagina di ricevuta è una vista in modo che non possa inserire JavaScript nell'intestazione poiché interesserebbe ogni pagina che lo utilizza.

Qualcuno sa come mi impedisce il pulsante Indietro in questa circostanza?

+0

Questo sarà un codice javascript per farlo. C# non ha nulla a che fare con esso, in quanto il C# è tutto sul lato server. Sono sicuro che puoi cercare StackOverflow per la risposta a questo, però. [Modifica: ho effettuato la ricerca per te.] (Http://stackoverflow.com/search?q = prevenire + indietro + pulsante + browser) – Gromer

+0

Inoltre, se si utilizzano sezioni nei file Razor, è possibile inserire javascript nella pagina da un file Razor specifico della vista parziale. Controlla questo blog per maggiori informazioni: http://weblogs.asp.net/scottgu/archive/2010/12/30/asp-net-mvc-3-layouts-and-sections-with-razor.aspx – Gromer

+0

Can ' lo scripting è disabilitato sul browser che ignorerebbe questo? – ErocM

risposta

14

Una possibilità è escludere la pagina a cui non si desidera tornare dalla memorizzazione nella cache sul client. Questo potrebbe essere fatto impostando le intestazioni di risposta appropriate. Ecco un esempio con un filtro azione personalizzato [NoCache] che è possibile utilizzare per decorare l'azione del controller corrispondente.

+0

Perfetto !! Grazie mille! – ErocM

6

In primo luogo, se la pagina precedente ha inviato dati al server, è meglio impostare Redirect(...) in un'altra azione dopo l'elaborazione corretta, per evitare di inviare nuovamente i dati su "Aggiorna".

Poi anche impostare la pagina per scadere, in modo che il pulsante Indietro non funziona:

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

+0

grazie, ho estratto anche questa risposta! – ErocM

3

stai chiedendo la domanda sbagliata. Non provare a disabilitare "indietro" sul client. Questo sarà destinato a fallire; potresti essere in grado di renderlo più difficile, ma non vincerai mai quella battaglia. Invece dovresti riscrivere la pagina in questione in modo tale che elaborerà la carta di credito solo una volta. Dovresti (sul server) "ricordare" che hai elaborato la carta di credito in modo che se l'utente torna alla pagina per inviarlo di nuovo puoi semplicemente dare loro un messaggio di errore che dice "hai già inviato queste informazioni, non puoi invia questa richiesta due volte ".

Ora, ci sono diversi modi per raggiungere questo obiettivo generale, e alcuni sono migliori di altri, ma questo è l'obiettivo che è necessario raggiungere.

Un modo per farlo è quello di andare ad ogni pagina che reindirizzerà l'utente a questo modulo di carta di credito; appena prima di inviare la richiesta aggiungi qualcosa alla sessione di quell'utente (ad esempio "pendingCreditCardSubmission" = true) Dopo aver inviato la richiesta, verifica la variabile di sessione. Se è vero, invia la richiesta e impostala su false, se è false o non presenti, quindi invia un messaggio di errore all'utente.

+0

Qui; avere un uppie su una risposta davvero vecchia! –

1

Questo è come abbiamo fatto:

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; 
    } 

} 

Dopo questo è possibile implementare neanche nella portata generale o nell'ambito del controllore.

1

È passato molto tempo da quando è stato richiesto, ma la mia correzione era l'aggiunta di [NoCache] sopra la classe WebPageController.

[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() 
      } 
     }; 
    }