Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to do URL Rewriting without query parameter doubling its value?

I have to following URL:

http://example.org/sessionstuff/kees/view.aspx?contentid=4&itemid=5

It needs to be rewritten so it will go to:

http://example.org/sessionstuff/view.aspx?site=kees&contentid=4&itemid=5

Basically it will take the kees value and put it as a site parameter. I'm using the IIS URL Rewrite module that uses rules in my web.config. I've added the following code to my web.config:

<rule name="RedirectSite" stopProcessing="true">
    <match url="^(\D[^/]*)/(.*)$" />
    <action type="Rewrite" url="{R:2}?site={R:1}" />
</rule>

Everything works fine, but when I do a postback, the site parameter is doubled. I've tested this by using the following code on my .aspx page:

<h3>Querystring</h3>
<ul>
    <% foreach (string key in Request.QueryString.Keys)
        Response.Write(String.Format("<li><label>{0}:</label>{1}</li>", key, Request.QueryString[key])); %>
</ul>
<asp:Button runat="server" Text="Postback" />

First time

Querystring
site: kees
contentid: 4
itemid: 5

Second time

Querystring
site: kees, kees <--- double
contentid: 4
itemid: 5

How to prevent the site parameter from duplicating itself? Each postback will add another value.

Note: the other query parameters must be present, so using appendQueryString="false" seems not an option.

like image 949
Kees C. Bakker Avatar asked Nov 04 '22 17:11

Kees C. Bakker


1 Answers

It looks like this could be solved by not rewriting the URL if it already contains the site= parameter (regardless of where in the query string it's located). So how do we do that?

Check out number 9 here: http://ruslany.net/2009/04/10-url-rewriting-tips-and-tricks/

I don't have a way to test this now, but I reckon something like this should work:

<rule name="Query String Rewrite">
  <match url="^(\D[^/]*)/(.*)$" />
  <conditions>
    <add input="{QUERY_STRING}" pattern="^((?!site=).)*$" />
  </conditions>
  <action type="Rewrite" url="{R:2}?site={R:1}" />
</rule>

NOTE: I am not great at rule rewriting, but this regex ^((?!site=).)*$ matches when the string DOES NOT contain site= and this is when you want your rewrite rule to operate, hence me adding that as a condition. I reckon you may be able to do this more efficiently.

What I am trying to do here is say: Let's rewrite the rule, but only if it doesn't already contain the site parameter.

I hope this is enough for you to answer the question!

===

This seems to work:

<rule name="RedirectSite" stopProcessing="true">
    <match url="^(\D[^/]*)/(.*)$" />
    <conditions>
        <add input="{QUERY_STRING}" pattern="^((?!site=).)*$" />
    </conditions>
    <action type="Rewrite" url="{R:2}?site={R:1}" />
</rule>


<rule name="RedirectSite2" stopProcessing="true">
    <match url="^(\D[^/]*)/(.*)$" />
    <conditions>
        <add input="{QUERY_STRING}" pattern="site=" />
    </conditions>
    <action type="Rewrite" url="{R:2}"  />
</rule>
like image 148
Tom Chantler Avatar answered Nov 09 '22 10:11

Tom Chantler