Keeping site root url clean without query string


References

SEO is becoming more and more important issue these days, and your site root url can lose its SEO rank if there are too many different query string attached such as www.yoursite.com/?a=b&b=c and www.yoursite.com/default.aspx?wt=129. It will be nice you can keep the site root clean lik www.yoursite.com

My company employed Scrum from this year and in March sprint, the above was one of the user stories I worked on.

The implementation logic is like this

One tricky bit is Request.QueryString is read only property. So you need to find a private value that the property uses inside. I could do that using .Net reflector and it is _queryString. Using Reflection, you can set the value of a private variable.

The followings are the codes I wrote for this. Of course, I could not write this without the help from the above links.

[sourcecode language='c#']

        protected override void OnInit(EventArgs e)
        {
            if (!IsPostBack)
            {
                if (Request.QueryString.Count > 0)
                    RedirectToCleanSiteRootUrl();

                if(Request.Cookies["QS"]!= null)
                    PopulateQueryStringFromCookie();
            }

            base.OnInit (e);
        }

        private void RedirectToCleanSiteRootUrl()
        {
            HttpCookie cookie = new HttpCookie("QS");
            foreach (string key in Request.QueryString.AllKeys)
            {
                cookie.Values[key] = Request.QueryString[key];
                cookie.Expires = DateTime.Now.AddDays(1d);
            }
            Response.Cookies.Add(cookie);

            PageUtility.RedirectPermanent("/");
        }

        private void PopulateQueryStringFromCookie()
        {
            NameValueCollection collection = (NameValueCollection) Request.GetType().GetField("_queryString",
                BindingFlags.NonPublic | BindingFlags.Instance).GetValue(Request);
            PropertyInfo readOnlyInfo = collection.GetType().GetProperty("IsReadOnly",
                BindingFlags.NonPublic | BindingFlags.Instance);
            readOnlyInfo.SetValue(collection,false,null);

            collection.Add(Request.Cookies["QS"].Values);
            Response.Cookies["QS"].Expires = DateTime.Now.AddDays(-1d);
        }

[/sourcecode]