Sie sind auf Seite 1von 7

Top of Form

• HOME
• ARTICLES
• ADVERTISE
• ABOUT
• CONTACT

Aug24200821
0tweetsretweet

URL REWRITING IN ASP.NET WEB


APPLICATIONS
I hope you hate URLs that look like this www.mysite.com/page.aspx?
something=1&somethingelse=15&other=abcd&category=32. If you do, let's have a little

reminder on rewriting URLs. But, if you don't, please take this article seriously :)

So, you hate such URLs

Or you'll hate it after you realize how easy it is to make it nicer. Besides all, URL rewriting
will improve your rankings on search engines. Search engines like Google will easily index
your "static" URLs, instead of dynamic URLs.

There are several ways to accomplish URL Rewriting. I'll explain how to do this by using
HttpModule and how to overcome the postback bug that is the outcome of URL rewriting.
Suppose you have a content management system that stores entire pages in the database.
So you can have a Home page, and Home page can have sections Products and Services,
and each one of these can have their own child pages or sections, and so on.

So we want dynamic URL like this: Default.aspx?SectionID=5&ItemID=22 to look like


/catalogue/furniture/chairs/chair5.aspx or whatever the business logic requirement is.

In the example in this article I will not use a database in order to keep it simple, but you
imagine there is a database that keeps the URL for each page. I'll use hard-coded Dictionary
that will keep some sample pages.

Note: You can download the full code in the attachment.

First, we'll make a data access object that will search the database for requested url and
return its dynamic url. These are the methods in SampleDAO that will simulate the database
and getting the url from there:

public string GetRealPath(string requestedUrl)


{
string path = "";
Dictionary<string, string> paths = GetPathsFromDatabase();
if (paths.ContainsKey(requestedUrl))
paths.TryGetValue(requestedUrl, out path);
return path;
}

private static Dictionary<string, string> GetPathsFromDatabase()


{
Dictionary<string, string> paths = new Dictionary<string, string>();
paths.Add("/URLRewrite/FirstSection/Default.aspx".ToLower(), "/URLRewrite/Default.aspx?
SectionID=1");
paths.Add("/URLRewrite/SecondSection/Default.aspx".ToLower(),
"/URLRewrite/Default.aspx?SectionID=2");
paths.Add("/URLRewrite/FirstSection/Page1.aspx".ToLower(), "/URLRewrite/Default.aspx?
SectionID=1&Item=1");
paths.Add("/URLRewrite/FirstSection/Page2.aspx".ToLower(), "/URLRewrite/Default.aspx?
SectionID=1&Item=2");
paths.Add("/URLRewrite/SecondSection/Page1.aspx".ToLower(), "/URLRewrite/Default.aspx?
SectionID=2&Item=1");
paths.Add("/URLRewrite/SecondSection/SubSection/AnotherOne/Page5.aspx".ToLower(),
"/URLRewrite/Default.aspx?SectionID=2&Item=5");
paths.Add("/URLRewrite/Default.aspx".ToLower(), "/URLRewrite/Default.aspx");
return paths;
}

What does this means? When you create links on your web pages, you will no longer use
query parametrised URLs but rather static URLs. Now what? If you request a page that
doesn't exist, HttpException will be thrown or default redirection will occur, but this is the
place where Rewrite module comes in.

Rewrite module (in our Example UrlRewriteModule) implements IHttpModule interface. This
means you will have to implement two methods: Init and Dispose. Init method is more
important. It accepts HttpApplication and lets you hook on whatever you want. In our case
we'll hook on Application BeginRequest event so that we can read a requested URL each
time a new request begins its lifecycle.

Look at the code below. In the Application_BeginRequest event handler we get the
requested url which is a static URL, and search the database to find the corresponding
dynamic url.

public void Init(System.Web.HttpApplication app)


{
app.BeginRequest += new EventHandler(Application_BeginRequest);
}

private void Application_BeginRequest(object sender, EventArgs e)


{
System.Web.HttpApplication app = (System.Web.HttpApplication)sender;
string requestedUrl = app.Request.Path.ToLower();

string realUrl = GetRealUrl(requestedUrl);

if (!String.IsNullOrEmpty(realUrl))
app.Context.RewritePath(realUrl, false);

}
private string GetRealUrl(string requestedUrl)
{

// Implement your own logic here

SampleDAO sampleDAO = new SampleDAO();


return sampleDAO.GetRealPath(requestedUrl);
}

There is one more thing to do before this handler becomes fully functional. We have to
register it in web.config file. We just have to add a new httpModule in the system.web

section. Under nameyou have to type it's class name, and under type you'll have to type it's

full assembly name. Since our module is in the current project in App_Code folder, we'll just
provide its name as a type.

<httpModules>
<add name="UrlRewriteModule" type="UrlRewriteModule"/>
</httpModules>

So, what's the problem?

And that's all you need to make it work. However, there is a problem with postback when

you are using URL rewriting. Here's the problem: the action attribute of the server-

side form tag on your page will point to the original page, and it's url is not a static one, but

rather dynamic. So you will loose your URL rewrite functionality on each postback.

The solution is to "tweak" the output of the action attribute. This approach is known as

Control adapter architecture.

Anyway, we'll just have to add a new .browser file and register our
FormRewriterControlAdapter.
<browser refID="Default">
<controlAdapters>
<adapter controlType="System.Web.UI.HtmlControls.HtmlForm"
adapterType="FormRewriterControlAdapter" />
</controlAdapters>
</browser>

FormRewriterControlAdapter class inherits from System.Web.UI.Adapters.ControlAdapter.


The code is quite simple, so check it out below:

public class FormRewriterControlAdapter : System.Web.UI.Adapters.ControlAdapter


{
protected override void Render(HtmlTextWriter writer)
{
base.Render(new RewriteFormHtmlTextWriter(writer));
}
}

public class RewriteFormHtmlTextWriter : HtmlTextWriter


{
public RewriteFormHtmlTextWriter(HtmlTextWriter writer)
: base(writer)
{
this.InnerWriter = writer.InnerWriter;
}

public RewriteFormHtmlTextWriter(System.IO.TextWriter writer)


: base(writer)
{
base.InnerWriter = writer;
}

public override void WriteAttribute(string name, string value, bool fEncode)


{
if (name == "action")
{
HttpContext Context = HttpContext.Current;
if (Context.Items["ActionAlreadyWritten"] == null)
{
value = Context.Request.RawUrl;
Context.Items["ActionAlreadyWritten"] = true;
}
}
base.WriteAttribute(name, value, fEncode);
}
}

And that fixes the problem entirely.

Conclusion

This is all you have to do to make URL rewriting work properly. The logic for getting the
corresponding dynamic URL for the requested one can be different. You can store both static
and dynamic paths in a database and perform a search, you can use regular expressions,
you can create the methods for parsing the requested URL and search for the item in the
database, or you can implement your own custom logic.

WITH SUPPORT FROM

Written by Janko in Tutorials, tagged under asp.net


Share:

21 COMMENTS - SHOW THEM AND LEAVE YOURS


Comments are closed

8775 readersSubscribe by emailFollow me


Advertise Here

Copyright © Janko Jovanovic 2008-2010.


JankoAtWarpSpeed is made with BlogEngine.NET, ASP.NET and jQuery. IE6 isn't supported.

GO TOP

Bottom of Form

Das könnte Ihnen auch gefallen