Sponsored By Aspose - File Format APIs for .NET

Aspose are the market leader of .NET APIs for file business formats – natively work with DOCX, XLSX, PPT, PDF, MSG, MPP, images formats and many more!

A back button for asp.net pages

For my app I needed a back button. Internet explorer and other browsers have back buttons, most mice have them as well but I needed my own small link to drop on my forms. Implementing it was no big deal, given you consider one essential quirk. After browsing around on the web I consider it worthwhile to share my findings.


The essential thing is what back really stands for. When an user is working with an aspx page she will regularly post back to the page leading to many renderings of the same url. By default back is back to the previous request. An application like Community Server (which is an asp.net app) works this way. Write you comment and click submit. When you click the back button of your mouse after that you’ll be back editing the comment. When you click submit again it might look like you ‘re posting an updated comment. In reality CS does receive a new comment. (Don’t try this at home, to prevent comment spamming CS blocks posting comments in that pace). To give the user a better user experience the smartNavigation property of an asp.net webform comes to the help. Setting it to true will redirect the user to the previous page when the back button is clicked. It does this by some script magic. Alas smartNavigation can play some nasty tricks on you when you try to redirect from a page which has it enabled.


In code you can see from which url the user came in the UrlReferrer property of the Request.. This always show the url of the last roundtrip, whether smartNavigation is switched on or off. So it will be the url of the page itself on a postback. On the first rendering of the page it will contain the intended page the user came from. So checking postback in combination with the referrer should do to find the desired url. The url has to be stored over roundtrips. On the best example I found on the web, by master of mystery Juval Löwy, it is stored in the session. This is a full demo ((free) registration required) where clicking a linkbutton performs a redirect to an URL. But besides problems with  smartnavigation I think the viewstate would be a better place to store the url than the session.


I use a plain HyperLink. The essence of my back link boils down to


private void Page_Load(object sender, System.EventArgs e)
{
   if (! IsPostBack)
      HyperLink1.NavigateUrl = Request.UrlReferrer.AbsoluteUri;
}
 

The NavigateUrl is set on the first request and will be saved over roundtrips in the viewstate.


As I am a bad and a lazy typist I don’t want to code these lines again and again. Let’s make it a custom control. Take these steps:



  • Add a new project, a Web ControlLibrary

  • Delete the webusercontrol1

  • Add a new item to the library, a Web Custom Control. Give it a real name

  • Delete all generated implementation code

  • Copy in this code

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;

namespace ButonBacklLibrary
{
    /// <summary>
    /// Summary description for MyBackButton.
    /// </summary>
    [ToolboxData(“<{0}:MyBackButton runat=server></{0}:MyBackButton>”)]
    public class MyBackButton : System.Web.UI.WebControls.HyperLink
    {
        protected override void OnLoad(EventArgs e)
        {
            if (! Page.IsPostBack)
                base.NavigateUrl = Page.Request.UrlReferrer.AbsoluteUri;
            base.OnLoad (e);
        }

        [Browsable(false)]
        public new string NavigateUrl
        {
            get
            {
                return base.NavigateUrl;
            }
        }
    }
}
 

The MyBackButton inherits from the HyperLink control. In the overriden OnLoad method the code to get the referral url is executed and stored in the NavigateURL property of the base, HyperLink, class. It no longer makes sense to manipulate the NavigateURL property of the back control in the designer or from code. I cannot override the property as it is not virtual. Using the new keyword the original property is shadowed. In code and in the designer my version of the property named NavigateURL is used. The implementation of the property can still get to the inherited property. The property getter just reads the base property, but the setter property has gone. I can no longer change the URL from code. By setting the [Browsable(false)] attribute on the property it will also be gone from the property window in the designer.


To get this button into the VS toolbox:



  • Right click the toolbox

  • Choose Add/Remove items

  • In the dialog click the browse button

  • Select the library we just built It’s the dll in the bin\debug or bin\release directory

  • The control will show up in the toolbox.

You can start using the control in you project. Debugging works well, breakpoints set in the control’s source will be hit.


Now you have a back button which is independent of the smartNavigation and session settings. But it does need the viewstate. Fiddling with that is another story.

This entry was posted in ASP.NET. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • SarahLgordon

    Simply amazing article! Unfortunately, I found this article too late – I already found the answer on another service. Filling out forms is super easy with PDFfiller. Try it on your own here RCP-E 74.14 and you’ll make sure how it’s simple.http://goo.gl/CkWqWt

  • KaylaGTurnball1590

    My children were wanting VA 10-7055 last month and used an online service that has lots of form templates . If people are requiring VA 10-7055 too , here’s http://goo.gl/lZeGbQ

  • Raj Sharma

    aaaaaaaaaaaaaaaaaaaaaaaaaa

  • Taqijawaid

    it works!!! thank u!!! 😀

  • Rasberry21

     Nice one . Thanks

  • As

    Nice one

  • Rahul

    This worked perfectly for me…..

  • Vijith77

    You can try using the HttpResponse.Cache property if that would help:

    Response.Cache.SetExpires(DateTime.Now.AddSeconds(60));
    Response.Cache.SetCacheability(HttpCacheability.Public);
    Response.Cache.SetValidUntilExpires(false);
    Response.Cache.VaryByParams[“Category”] = true;

    if (Response.Cache.VaryByParams[“Category”])
    {
    //…
    }

    Or could could block caching of the page altogether with HttpResponse.CacheControl, but its been deprecated in favor of the Cache property above:

    Response.CacheControl = “No-Cache”;

    Edit: OR you could really go nuts and do it all by hand:

    Response.ClearHeaders();
    Response.AppendHeader(“Cache-Control”, “no-cache”); //HTTP 1.1
    Response.AppendHeader(“Cache-Control”, “private”); // HTTP 1.1
    Response.AppendHeader(“Cache-Control”, “no-store”); // HTTP 1.1
    Response.AppendHeader(“Cache-Control”, “must-revalidate”); // HTTP 1.1
    Response.AppendHeader(“Cache-Control”, “max-stale=0″); // HTTP 1.1
    Response.AppendHeader(“Cache-Control”, “post-check=0″); // HTTP 1.1
    Response.AppendHeader(“Cache-Control”, “pre-check=0″); // HTTP 1.1
    Response.AppendHeader(“Pragma”, “no-cache”); // HTTP 1.1
    Response.AppendHeader(“Keep-Alive”, “timeout=3, max=993″); // HTTP 1.1
    Response.AppendHeader(“Expires”, “Mon, 26 Jul 1997 05:00:00 GMT”); // HTTP 1.1

    for more doubts http://innovationplanet.wordpress.com

  • Vijith

    http://innovationplanet.wordpress.com/
    this site helps you a lot

  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    Having left a page it’s state is gone. That’s the nature of a webpage.
    You need to save the state the page was in when left. FI in the session.
    When coming back to this page you have to restore it to the state. FI from the session

  • Mahesh

    Hi
    I am implementing a webpage where user will be able to register their product. however after registration, I navigate user to the confirmation page where user confirm the details he has entered, if he want to edit it he can go back by clicking go back button and edit it. I have some hidden dropdown which are only shown if user chose specific catagories. But when I click go back button the, the dropdown list goes back to hidden and I cannot see them. Furhter, I have two dropdown where one is State and another is City. When I click go back, the City doesn’t retain selected. Could you please guide me how can I implement this using C# backend and asp.net

  • http://www.julianomarcon.com.br Juliano Marcon

    Well. For me, this is a good code. But in case when UrlReferr is Null, the parameters for javascript is a good idea.

    My code is here:

    if (!Page.IsPostBack)
    {
    if (Page.Request.UrlReferrer == null)
    {
    base.Attributes.Add(“OnClick”, “history.go(-1)”);
    }
    else
    {
    base.NavigateUrl = Page.Request.UrlReferrer.AbsoluteUri;
    }
    }
    base.OnLoad(e);

  • http://- Vijay Kumar

    Thank for the code. Good Job….

  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    Decrypt the querystring 😕

  • santhosh

    Page.Request.UrlReferrer.AbsoluteUri; is throwing error when i use with encrypted Querystring. Can you please suggest me how to solve this?
    Thanks in Advance.

  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    That doesn’t consider “smartnavigation”

  • seth

    easiest asp.net backbutton is to add an attribute to the asp.net button. Add it in the Page_Load section:

    Button1.Attributes.Add(“onclick”, “javascript:history.go(-1);return false”);

    Simulates a browser back button click.

  • http://tt ttt

    tt

  • http://gg gg

    gg

  • http://woodassoc.us/blog/b2e/index.php/jw John

    You could also use a Stack Collection object to record the addresses that pertinent. Like removing the data entry pages and only the view pages.

    Using it at work for a internal page and works like a charm. Dont have to validate addresses, attach anything to a button/hyperlink/etc. just pop the last address pushed to the stack object and WAMO, you have a good redirect.

    As i stated, this logic should not be used when a user is navigating into a DataEntry page.

  • http://www.allinterviewquestions.net Abdul Rauf

    When I use the window.location.href=”some new page”, then on the new page request.urlreffer is null.

  • http://codebetter.com/members/pvanooijen/default.aspx pvanooijen

    What do you mean ? In the brower it’s just a hyperlink. No more, no less

  • shane

    don’t this result to a two-page loop?

  • uuuu

    fg

  • rth

    fgh

  • Ray Costanzo

    when i navigate to a page through back button of internet explorer iam not able to get its address using Page.Request.UrlReferrer.AbsoluteUri. can anybody solve this problem

  • arnold

    horrible!!!

  • http://www.rezashirazi.com Reza Shirazi

    Very nice! Thank you

  • Niraj

    This is not working in Internet explorer

  • Joel

    This works fine for hyperlink in asp.net but for Sharepoint Toolbarbutton Navigateurl looked also fine as i tested with f5 in page and all until i have problems if i just click in the url bar and type enter, like going again to the same page there:

    Object reference not set to an instance of an object

    Heres the page load code

    protected void Page_Load(object sender, EventArgs e)
    {
    if (!Page.IsPostBack)
    {
    toolbarbutton1.NavigateUrl = Page.Request.UrlReferrer.AbsoluteUri;
    }
    }

    what i am doing wrong here? Or this is not a good option for sharepoint controls?Thanks

  • http://codebetter.com/blogs/peter.van.ooijen/ pvanooijen

    The back button is part of your browser and hard, if not impossible, to reach from your code.. Every browser is different and besides that many a mouse or keyboard has a back button as well.

    It’s a better strategy to make your webapp behave well when the back button is fired. Check the smartnavigation settin gin the web.config

  • Namrata

    I wish to know can we freeze the back button of the web browser we are using. If so please help me soon as I’m new to the coding world.

  • http://codebetter.com/blogs/peter.van.ooijen/ pvanooijen

    I think you should restore the selectedindex of the gridview. Store that somewhere (session/cookie ?) and set it in the page load when returning to the page.

  • momobnj

    Clarification: I click a link inside the gridview, which takes me to another page. I want to return from that page to the gridview page with the search stuff.

    And no, I don’t want to have the linked info on the same page in another gridview or details view; I want to keep them separate.

  • momobnj

    Didn’t work for me, either. I have a search page, with a gridview showing search criteria (from text boxes) results. When I click a link inside the gridview, I want to return to the gridview page from the linked page, but all I get is the original search page in its initial state, with nothing in the text boxes and no gridview. Any suggestions for returning to the gridview with its intact search criteria?

    Thanks in advance. Can’t tell you how frustrating this is.

  • http://codebetter.com/blogs/peter.van.ooijen/default.aspx pvanooijen

    Like some other comments state: several AV packages strip this property from the HTTP request. Nothing you can do about that.

    And don’t get me started on smartnavigation (just search my blog on it:))

    Your back button has to be better than the browser’s one, it should take the user a page back, and not a roundtrip (ispostback). Not all brwoser see this difference.

  • Mako

    Tried this and it didn’t work. Page.Request.UrlReferrer.AbsoluteUri doesn’t exist, regardless of the history before I arrive at my page.

    Why oh why is a back button in .NET so frigging HARD?
    Why oh why do moronic users demand back buttons when there’s already one THERE?

  • http://codebetter.com/blogs/peter.van.ooijen/ pvanooijen

    When the refrerrer is gone it’s gone. Nothing you can do about that. Like Geoff said in the fisrt comment.
    The browser’s back button will also be disabled. What the control could do is set its enabled state to false when there’s no referrer.

    if (! Page.IsPostBack)
    {
    if (Page.Request.UrlReferrer == null)
    this.enabled = false;
    else
    base.NavigateUrl = Page.Request.UrlReferrer.AbsoluteUri;
    }

    Concerning Norton : These utilities mess up such an enormous amount of things I can only advise to stop using them. There are a lot of alternatives which do work and do not have the side-effects.

  • Don Hesse

    I think I see two issues with the code for the back button. I’m hoping that I’m wrong, so please let me know if I am.
    1. I’ve found that at least one anti-spyware software (Norton 2005) strips the UrlReferrer information, making UrlRefferer = null.
    2. You should probably add a test to see if the UrlRefferer is null before setting another object to it – just in case of #1.
    Thanks. I’m hoping you know of a work around.

  • Joe

    I get following error while trying this:

    Object reference not set to an instance of an object.
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.

    Source Error:

    Line 145:
    Line 146: if (!IsPostBack)
    Line 147: HyperLink1.NavigateUrl = Page.Request.UrlReferrer.AbsoluteUri;

  • http://codebetter.com/blogs/peter.van.ooijen/ pvanooijen

    thanks Geoff.

    In case the referrer is gone from the header it’s no better than the normal back button. Where you see the same thing happening. As it’s a custom control you could give it default back page, like the app’s home.

  • http://codebetter.com/blogs/geoff.appleby/ Geoff Appleby

    Are you using this for an internet facing public app?

    Be careful of using the referrer if you are – there’s a lot of proxies out there that silently remove the http referrer request header, so by the time the request is received, there’s no referrer available to get a URL out of.

    Other than that, very cool :)