views:

435

answers:

4

I am building a web-store that uses URL encoding extensively.

I have a list of Departments & Categories in my database which I use to generate the links. These are, of course, URL encoded before they are sent.

Some Typical Links are...
/MySite/Store/Countertop+Equipment/Can+Openers.aspx
/MySite/Store/Dinnerware.aspx /MySite/Store/Kitchen/Pastry%2f+Decorating.aspx

In my HTTPHandler I call app.Request.Path to obtain the current path. The string returned by this call is no longer URL encoded which is making it impossible for me to parse correctly. Once the URL encoding is lost
/MySite/Store/Kitchen/Pastry%2f+Decorating.aspx becomes
/MySite/Store/Kitchen/Pastry/Decorating.aspx.

This is obviously breaking the method that converts the URL to a QueryString.

Anyone know how to fix this?

Here is the core of my HTTPHandler

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 realUrl = GetRealUrl(app.Request.Path);

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

I really appreciate your help!

+1  A: 

Try the AbsolutePath or PathAndQuery properties on the Request object. Both of them should maintain the url encoding.

BStruthers
+2  A: 

You cannot use Request.Url (including Url..PathAndQuery, AbsolutePath etc) as its OriginalString is already decoded.

So there is no point to use Request.Url at all and you can try to play with following:

Or in a worst-case scenario you'll need to parse the Url:

    [Test]
    public void RewriteProoveOfConcept() {
        var path = @"/MySite/Store/Kitchen/Pastry%2f+Decorating.aspx";
        var res = Regex.Replace(path, @"/(.+)/(.+)/(.+)/(.+)\.aspx", @"/$1/YourPage.aspx?category1=$2&category2=$3&category3=$4");
        Assert.AreEqual(@"/MySite/YourPage.aspx?category1=Store&category2=Kitchen&category3=Pastry%2f+Decorating", res);
    }

This shows how you can get the URL:
/MySite/YourPage.aspx?category1=Store&category2=Kitchen&category3=Pastry%2f+Decorating
from:
/MySite/Store/Kitchen/Pastry%2f+Decorating.aspx

Additionally consider using Routing instead of UrlRewrite.

Cheers,
Dmitriy.

Dmytrii Nagirniak
I went through the entire property / method tree of request and unfortunately the problem appears to be upstream even further, possibly in IIS. Anyways thank you for the detailed response that at least got me on the right track of where to check.
apocalypse9
A: 

You can UrlEncode the URL before parsing it. Or better yet, keep URL's non-encoded in database. You don't even need to encode them if you use HyperLink control.

Pavel Chuchuva
Unfortunately Url Encoding it again before parsing won't help as it will encode all the slashes whether they are part of the path or part of the text.
apocalypse9
A: 

It turns out that the issue is occurring in IIS before .Net even gets its hands on the request. It appears that this is a dead end.

An additional word of warning is that my IIS test server (XP) was rejecting requests containing encoded amperstands as a security risk and could not be persuaded to cooperate with anything short of a registry edit. Not sure if this goes for all versions, but even if a server variable can be retrieved this seems like another good reason to use a different tactic.

Here is the follow-up question with the accepted solution-

http://stackoverflow.com/questions/1288630/asp-net-url-encoding

apocalypse9