Geeks With Blogs

@azamsharp
  • azamsharp The WWDC app says that there are new videos but there is nothing under videos!!! about 497 days ago
  • azamsharp Can I post my opinion on iOS 7 Beta or is it under NDA or something? about 497 days ago
  • azamsharp iOS 7 BETA installed successfully! about 497 days ago
  • azamsharp iOS 7 BETA installed! Now restoring! I am on NET10 which uses AT&T network. Hopefully 3G will still work! Lets c.. about 497 days ago
  • azamsharp The missing of button borders in Xcode 5 makes it hard to determine the clickable area. about 497 days ago
  • azamsharp I might wait for iOS to be released before I can put it on my device! Don't want a bricked or unstable device! about 497 days ago
  • azamsharp Android has many features that no one uses, number of versions that no one upgrades to and thousands of apps that no one pays for. about 497 days ago
  • azamsharp Maybe it is just me but the new iOS 7 UI looks like Windows Phone 8 UI! #maybeIamCrazy about 498 days ago
  • azamsharp Anyone using H20 network upgraded to iOS 7 BETA Keep me updated if you face any problems. about 498 days ago
  • azamsharp @merowing_ You already downloaded it! I cannot even load the developer's website! :( about 498 days ago

AzamSharp Some day I will know everything. I hope that day never comes.

When developing www.RefactorCode.com I was advised to create friendly URLS so that search engines like Google, Yahoo, Live Search etc would be able to index it. Ben Sheirman suggested that I should try out IRouteHandler interface which was originally part of the ASP.NET MVC Framework. I implemented the URL-Rewriting solution which worked on my local machine but failed on the production. The web host guys told me that currently they don't support ASP.NET 3.5 Extensions Preview (I don't think that was the problem.)

My next solution involved using the RewritePath method of ASP.NET. For that I created a small class called "Route" which will hold the new routes.

 public class Route
    {
        private string _key;
        private string _url;

        public string Key
        {
            get { return _key; }
            set { _key = value; }
        }

        public string Url
        {
            get { return _url; }
            set { _url = value; }
        }
    }

The routes are setup in the Application_Start event in the Global.asax file.

public class Global : System.Web.HttpApplication
    {
        private static List<Route> routes = null;

        protected void Application_Start(object sender, EventArgs e)
        {
            // initialize the routes
            routes = new List<Route>()
            { new Route() { Key = "Categories", Url = "~/ProductsByCategory.aspx?id=" },
                 new Route() { Key = "Refactorings", Url = "~/SubmissionDetails.aspx?id=" }
            };
        }

    public static List<Route> GetRoutes()
        {
            return routes;
        }

In the above code I am setting up two routes one for the Categories key and the other for the Refactorings key. The HttpModule "UrlRewrite" is used to forward the route to the correct address.

public class UrlRewrite : IHttpModule
    {      

        public void Dispose()
        {
                  
        }

        public void Init(HttpApplication httpApplication)
        {
            // attach the begin request!
            httpApplication.BeginRequest += new EventHandler(httpApplication_BeginRequest);        
        }

        void httpApplication_BeginRequest(object sender, EventArgs e)
        {
            RegisterRoutes();
        }

      
        // Register the routes!       
        private static void RegisterRoutes()
        {
            HttpContext context = HttpContext.Current;
            string oldPath = context.Request.Url.ToString();

            var newRoute = (from route in Global.GetRoutes()
                            where oldPath.IndexOf(route.Key) > -1
                            select route).SingleOrDefault();

            if (newRoute == null) return;

            int i = oldPath.IndexOf(newRoute.Key);
          
                if (i > -1)
                {
                    int underScoreIndex = oldPath.IndexOf("_");
                    int startIndex = (i + newRoute.Key.Length + 1);
                    int numberOfCharacters = underScoreIndex - startIndex;

                    int id = Int32.Parse(oldPath.Substring(startIndex, numberOfCharacters));
                    context.RewritePath(newRoute.Url + id, false);
                }                                 
        }       
    }

Now, I need to display list of items with a custom URL. Here is the implementation of the CreateFriendlyUrlsForCategories method which is used to create custom URLS:

 public static string CreateFriendlyUrlsForCategories(int id, string title)
        {
            return String.Format("Categories/{0}_{1}", id, title.Replace(" ","_"));
        }

This will generate the following URL:

This is much cleaner than http://localhost:1688/ProductsByCategory?id=10. This will work fine on your local machine but as soon as you deploy it to the production it will result in a "404 Page Not Found" error. After much research and hair pulling I concluded that IIS6 is not capable of handling URLS with no file extensions (Please correct me if my assumption is wrong). So, to fix this problem I made a small change in my CreateFriendlyUrlsForCategories method.

 public static string CreateFriendlyUrlsForCategories(int id, string title)
        {
            return String.Format("Categories/{0}_{1}.aspx", id, title.Replace(" ","_"));
        }

Now, the requests for the pages will succeed and they will be routed correctly. I am pretty sure that you can also use the IRouteHandler for UrlRewriting with this change it will work correctly. Now the URLS will be generated like this:

One other thing that you must be careful with is using the ResolveUrl method when creating friendly URLs. Check out the code below:

<asp:Repeater ID="repCategories" runat="server">

<ItemTemplate>

<div>

<asp:HyperLink ID="hlCategoryName" NavigateUrl='<%# ResolveUrl(UrlRewritingDemo.Helpers.SiteHelper.CreateFriendlyUrlsForCategories((int)Eval("id"),(string)Eval("CategoryName"))) %>'
 runat="server" Text='<%# Eval("CategoryName") %>' />

</div>

</ItemTemplate>

</asp:Repeater>

The ResolveUrl will make sure that the URL you are referring is correct even though you are inside sub directories.

I will write an article on this topic and publish a link to that article on this post.

Posted on Tuesday, May 6, 2008 5:01 AM | Back to top


Comments on this post: UrlRewriting Pains and Fixes!!!

No comments posted yet.
Your comment:
 (will show your gravatar)
 


Copyright © Mohammad Azam | Powered by: GeeksWithBlogs.net | Join free