Search

May 31, 2008

Duplicate key/value pair in Querystring

I was facing a problem, when the Application_AuthenticateRequest get fails and redirects to login page of the system along with the ReturnUrl which contains the actualy requested url.

Problem was like my ReturnUrl contains the same key twice, which leads to crash in system.

Apart from this, I found in Trace that the ReturnUrl is fine at the requested Page.
like... I made request for http://www.imran/MyProfile.aspx?id=102; it shows 302 as [redirected flag] and the ReturnUrl get the value of http://www.imran/MyProfile.aspx?id=102, but when it goes to Login.aspx it shows 2 query string params.

1. ReturnUrl = http://www.imran/MyProfile.aspx?id=102
2. id=102

Here is the problem, we can see the id is part of ReturnUrl, but in this case it generates following redirection url

Login.aspx?ReturnUrl=http://www.imran/MyProfile.aspx?id=102&id=102

Now when I ask for Request["id"], which gives me value comma saperate like 101,102 and this is what we can say a bug.

After searching long I found the solution, which include the Event that we have to capture in Global.asax, and one property of Response object which sets/gets the Http location Header, here is the code.


protected void Application_EndRequest(object sender, EventArgs e)
{
if (Response.RedirectLocation != null && Response.RedirectLocation.Contains("ReturnUrl"))
{
Response.RedirectLocation = string.Format("{0}ReturnUrl={1}",
Response.RedirectLocation.Remove(Response.RedirectLocation.IndexOf("ReturnUrl")
, (Request.RawUrl.Contains("ReturnUrl") ?
Request.RawUrl.Substring(Request.RawUrl.IndexOf("ReturnUrl") + 10)
: Request.RawUrl
)
));
}
}

This will add the RawUrl into ReturnUrl so there will be no duplication.

6 comments:

Anonymous said...

This code won't compile in .NET 3.5 unless you move a parenthesis to after this line: Response.RedirectLocation.Remove(Response.RedirectLocation.IndexOf("ReturnUrl"))

Otherwise you are using the String.Remove(int, int) method instead of the String.Remove(int) method and since you return a string in your conditional statement the compiler chokes.

Good solution though as there aren't many out there

Anonymous said...

We are seeing the same issue on our Prod website as well .
Can you tell me the reason why the querystrings are being duplicated

Imran said...

I am not sure about the reason, have to go deep into authentication module to find out the problem.

Scott Whigham said...

The reason is so that you still have access to the original querystring values while on the login page. So when you see https://www.learnitfirst.com/GetStarted.aspx?ReturnUrl=/Course/WatchFreeVideo.aspx?CourseId=153&VideoId=1333&CourseId=153&VideoId=1333, you'll see both a URL encoded version of the params and a non-URL encoded version. The URL encoded version is used for determining where to send you after RedirectFromLoginPage whereas the non-Url encoded versions are for your use on the login page.

However, it sucks. Terribly. Good idea but doesn't work as intended :(

Cesar Alejandro Amezcua Tejeda said...

Request.QueryString["KeyQuery"].FirstOrDefault().ToString()

Cesar Alejandro Amezcua Tejeda said...

Hi!

Request.QueryString["KeyQuery"].FirstOrDefault().ToString()