What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

When I wrote the first post in this series, there was tremendous amount of interest generated and also a lot of feedback requesting to post some of the advanced features.  Like I said earlier, ASP.NET 4.0 has lots of new features some of them as simple as Page.Title whereas so as big as caching improvements.  This post covers one such feature which is Routing in Webforms.  Although Routing was available even in .NET 3.5 SP1, (check this excellent post by Phil Haack on implementing Routing in ASP.NET 3.5 with .NET 3.5 SP1), it was kind of less known.  Also the plumbing work was too much for getting it implemented.

However, this has been much simplified in ASP.NET 4.0.  To give a background, System.Web.Routing is the namespace that provides the all important RouteTable & PageRouteHandler class.  Initially System.Web.Routing was an integral part of ASP.NET MVC.  However, the team must have anticipated that Routing is more important even for Webforms and hence they moved this DLL outside the scope of just MVC and made it available to Webforms as well. 

Importance of Routing:  Getting friendlier URLs which help in better search engine optimization and indexing.  Cleaner URLs that can be bookmarked than the unfriendly querystring based approach.  As more and more URLs are available, the chances of improvement in search engine ranking becomes higher.  These are some of the general advantages of Routing and friendly URLs. 

Ok, now that the context is established, lets start with our sample.  To begin with, I am using Visual Studio 2010 Beta 1 (download link) and Northwind Sample Database (download link)

I created a “File – New Project – ASP.NET Web Application” leaving the default .NET 4.0 as the framework option. Then, I created a bunch of pages i.e Products.aspx, Categories.aspx and also the Global.asax (Add – New Item – Global Application Class)

On the Default.aspx page, I added a GridView and configured it to use the Northwind Database Connection String and the Categories Table therein.  I modified the auto-generated bound columns with a Template Column to accomodate our link to Categories Page.  The modified GridView code looks as below:-

<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
            AllowSorting="True" AutoGenerateColumns="False" CellPadding="4"
            DataKeyNames="CategoryID" DataSourceID="SqlDataSource1" ForeColor="#333333"
            GridLines="None">
            <AlternatingRowStyle BackColor="White" />
            <Columns>
               <asp:TemplateField HeaderText="CategoryName" SortExpression="CategoryName">
                    <ItemTemplate>
                   
    <a href="Categories/<%# Eval("CategoryName") %>"><asp:Label ID="Label1" runat="server" Text='<%# Bind("CategoryName") %>'></asp:Label></a>
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="Description" HeaderText="Description"
                    SortExpression="Description" />
            </Columns>
            <FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
            <HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" />
            <PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
            <RowStyle BackColor="#FFFBD6" ForeColor="#333333" />
            <SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
        </asp:GridView>

As you can see, the Item Template for Category Name is modified to sport a hyperlink to “Categories” page followed by the CategoryName itself.  This would mean that the URL for a category, say Beverages would point to Categories/Beverages

Similarly, on the Categories page, I added a GridView and configured it to use the “Allphabetical List of Products” Table.  I also modified the Bound field for ProductName to a template column to have a link to another Products Page.  The modified GridView code looks as below:-

<asp:GridView ID="GridView1" runat="server" AllowPaging="True"
           AllowSorting="True" AutoGenerateColumns="False" CellPadding="4"
           DataSourceID="SqlDataSource1" ForeColor="#333333" GridLines="None">
           <AlternatingRowStyle BackColor="White" />
           <Columns>
               <asp:TemplateField HeaderText="CategoryName" SortExpression="CategoryName">
                   <ItemTemplate>
                     
<a href="Products/<%# Eval("ProductName") %>"><asp:Label ID="Label1" runat="server" Text='<%# Bind("ProductName") %>'></asp:Label></a>
                   </ItemTemplate>
               </asp:TemplateField>
               <asp:BoundField DataField="QuantityPerUnit" HeaderText="QuantityPerUnit"
                   SortExpression="QuantityPerUnit" />
               <asp:BoundField DataField="UnitPrice" HeaderText="UnitPrice"
                   SortExpression="UnitPrice" />
               <asp:BoundField DataField="UnitsInStock" HeaderText="UnitsInStock"
                   SortExpression="UnitsInStock" />
               <asp:BoundField DataField="UnitsOnOrder" HeaderText="UnitsOnOrder"
                   SortExpression="UnitsOnOrder" />
               <asp:BoundField DataField="ReorderLevel" HeaderText="ReorderLevel"
                   SortExpression="ReorderLevel" />
               <asp:CheckBoxField DataField="Discontinued" HeaderText="Discontinued"
                   SortExpression="Discontinued" />
           </Columns>
           <EditRowStyle BackColor="#2461BF" />
           <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
           <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />
           <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />
           <RowStyle BackColor="#EFF3FB" />
           <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />
       </asp:GridView>

Note, while configuring above GridView, in the screen where we configure DataSource, I also added a where condition to accomodate the Route Request.  The screen looks as below:-

confscreen1

confscreen2

Note that I had selected the Where condition from the first screen and specified “CategoryName” under Column,“=” under Operator and “Route” under Source.  Also specified are the RouteKey “catname” and DefaultValue “Beverages”.  Post this, I just had to click on “Add” and then “Ok” to get a conditional select statement in the SQL DataSource (note: for the purpose of this demo, I have used SQL DataSource.  But this would work even if you used any other datasource type / written ADO.NET Code).  The “Route” type is new feature added under Source in Visual Studio 2010.

Once the above configuration is done, the SQL DataSource code looks as below:-

<asp:SqlDataSource ID="SqlDataSource1" runat="server"
           ConnectionString="<%$ ConnectionStrings:NorthwindConnectionString %>"
           SelectCommand="SELECT [ProductName], [QuantityPerUnit], [UnitPrice], [UnitsInStock], [UnitsOnOrder], [ReorderLevel], [Discontinued] FROM [Alphabetical list of products] WHERE ([CategoryName] LIKE '%' + @CategoryName + '%')">
          
<SelectParameters>
               <asp:RouteParameter DefaultValue="Beverages" Name="CategoryName"
                   RouteKey="catname" Type="String" />
           </SelectParameters>
       </asp:SqlDataSource>

I have also added a label to the page just to show the term used to filter and the value for that can be picked up from the Page.RouteData values in the codebehind as follows:-

protected void Page_Load(object sender, EventArgs e)
       {
           if (Page.RouteData.Values["catname"] != null)
           {
               lblDisplay.Text += "<b>" + Page.RouteData.Values["catname"].ToString() + "</b>";
           }
           else
           {
               lblDisplay.Visible = false;
           }
       }

Before getting into Route Configuration, I also added a DetailsView control in the Products.aspx page to show the complete details of a product.   And when configuring the DataSource for the DetailsView, I again specified the WHERE condition to the picked up from the RouteData that would come from the above GridView in Catagories Page.

Once this is done, all that is pending is to configure the Route Values.  In .NET 3.5 SP1 if you want to establish routing, you would have to manually create the WebFormRouteHandler Class and make sure all the pages inherit from this class.  However, in .NET 4.0, it has been much simplied.  All I had to do was open the Global.asax and add the following

protected void Application_Start(object sender, EventArgs e)
        {
             RouteTable.Routes.Add("ProductRoute", new Route("Categories/Products/{productname}",
       new PageRouteHandler("~/Products.aspx")));

            RouteTable.Routes.Add("CategoryRoute", new Route("Categories/{catname}",
       new PageRouteHandler("~/Categories.aspx")));
        }

(note you would need to add System.Web.Routing namespace to be able to use PageRouteHandler, RouteTable classes etc.,)

So, in the Default.aspx page, all the Catagories would have a link that points to /Categories/<CategoryName> and in the Categories.aspx page, all the ProductNames would have a link that points to /Categories/Products/<ProductName>

A typical URL is http://localhost/Categories/Condiments and http://localhost/Categories/Products/Aniseed%20Syrup

Note that similarly, we have close to 10 URLs for Beverages and around 80 URLs (a URL for each product as above) for Products in this particular application.

You can download the sample from  (Add your connectionstring to Northwind Database in the web.config file)

Cheers !!!

Print | posted on Thursday, August 20, 2009 7:21 AM

Comments on this post

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
Nice one,
Keep on writing :)

One question, is there any way in forthcoming release of ASP.net where I can encrypt entire URL or some part of it, so that it will be less hackable. Atleast the "QueryString" part. like
htp://www.localhost.com/products.aspx?jsafhsjdfrr454543ksdfkdsafjdsf

But still the parameters will be available to my ASP.Net controls.I hope I am not too demanding

Shail
Left by Shail on Aug 20, 2009 9:12 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
Shail, not 'built in' but it's pretty easy to achieve that...
Left by Scott Galloway on Aug 20, 2009 11:58 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
Cool!! This is really good!!!
Left by CodeDigest on Aug 20, 2009 9:54 PM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
nice article
Left by chandradev on Aug 21, 2009 12:54 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
I am not a rockstar developer so I dont know if this is reasonable request but I always cringe when I see strings instead of strongly typed data.

Obviously this has been thought about as the people behind asp.net are top quality developers but is there a reason why there is so much code like Page.RouteData.Values["catname"] throughout the platform?

Doesn't it break the DRY principle by spreading this out over the project? And its something that the compiler cant catch.

Still the feature itself is great, thanks for the post!


@Shail - If you did that then please take into account the SEO aspect that Google needs to able to see consistent urls to your pages if you want them indexing.



Left by rtpHarry on Aug 21, 2009 5:46 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
@rtpHarry - Strongly typed is good but can't be assigned to at runtime. In case of Page.RouteData.Values["catname"] you can change "catname" to anything at runtime..
Left by Vik on Aug 21, 2009 7:06 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
@rtpHarry
Well I need that for my In House Web site, Which is not going to be exposed to world.
My ideas is that I should write an HTTPModule for pre and pots Encryption and Decrption.

@Scott, can you give some suggestions for that ?
Left by Shail on Aug 22, 2009 2:59 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
Excellent stuff, another reason not to pick up that book on MVC I just bought....
Left by Jon on Aug 23, 2009 4:05 PM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
@Vik - the fact that it can be changed in this way is my problem. If you put put "catnames" instead of "catname" nobody is going to know until your website crashes.

An alternative would be to strongly type it into:
Page.RouteData.Values.CatName

I dont know if there are some situations where you would absolutely have to access it via ["catname"]? If there are I guess you could leave that in and also strongly type for day-to-day use.
Left by rtpHarry on Aug 29, 2009 7:53 AM

# re: What's new in ASP.NET 4.0 - Part II - Routing in Webforms

Requesting Gravatar...
Oh, gosh!
One more article with a lot of infrastructure code at interface. One more article for "drag-and-dropers" programmers.
I am sorry for them.
Left by Prodis on Sep 08, 2009 3:23 PM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
Nice one

It's really great post for developer who want their website to be more SEO optimized
Left by vikrant on Sep 20, 2009 4:42 PM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
I'm hiring somebody to make my own website and later on, do SEO to make my site rank higher. Can this help him?
Left by family law lawyer on Apr 06, 2013 6:50 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
I'm really interested in mastering SEO. This post of yours will really help me with what I'm doing now. Hope you can also post some of the advanced features of ASP.NET 4.0!

Brian
Left by Brian on Jun 07, 2013 6:15 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
I have a friend who has this interest in building web applications and I remember him telling me that he's trying to look for more tips on using ASP.NET 4.0. I'm not sure if he has come across this one. But, I will share this to him. Thanks for the information!

Alyssa Roy
Left by Alyssa Roy on Jun 20, 2013 6:51 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
When it comes to web apps development, ASP.NET is the best to choose!

Stephen Macdonald
Left by Stephen Macdonald on Jul 12, 2013 5:54 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
Thanks for showing us the sample. But, I have to run on it again as it gave me nosebleed! LOL! Thanks again!

Thomas Peart
Left by Thomas Peart on Aug 01, 2013 8:57 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
I have also selected the Where condition from the first screen and specified “CategoryName” under Column,“=” under Operator and “Route” under Source and it worked perfectly fine! Thanks for the tip!

Anthony Lee James
Left by Anthony Lee James on Aug 16, 2013 5:46 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
Thanks for the update of this ASP.net! We really appreciate it!
listing of lawyers online
Left by Amy on Aug 29, 2013 8:43 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
How can we get friendlier URLs to help optimize our own websites?
legal lawsuit
Left by Matthew on Sep 12, 2013 4:19 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
Awesome! Thanks! Do you have the Part III of these? Hope you can also share it here.
finding the best lawyers
Left by Alexander on Sep 26, 2013 2:19 AM

# re: What’s new in ASP.NET 4.0 – Part II – Routing in Webforms

Requesting Gravatar...
Thanks a lot for news. online-essay-writer.org So useful.
Left by Lena on Nov 24, 2013 2:37 AM

Your comment:

 (will show your gravatar)