C# Percentage Decoding - c#

I am trying to decode a percentage encoded string passed from a PHP script to my C# application. The PHP encrypts the data, so there are many special characters that I percentage encode.
Here's the string I'm passing in the URL:
%C9%90%04L%EFEA%D1U%AFi%CBc%3A%E5%D0%40Q%D6%1Bn%C9%C3%B5%0FT%FC%E5h%95m%EF%BF%24tB%A6%D1%08%3B%83%A1%CF%1B%99Zo%02
But it has trouble percentage decoding parts of it: when I fetch the query string, like so:
var queryString = HttpContext.Current.Request.QueryString;
var token = queryString["token"];
The variable token, though, equals this:
%C9%90%04L%EF%BF%BDEA%EF%BF%BDU%EF%BF%BDI%EF%BF%BDC%3A%EF%BF%BD%EF%BF%BD%40Q%EF%BF%BD%1BN%EF%BF%BD%C3%B5%0FT%EF%BF%BD%EF%BF%BDH%EF%BF%BDM%EF%BF%BD%24TB%EF%BF%BD%EF%BF%BD%08%3B%EF%BF%BD%EF%BF%BD%EF%BF%BD%1B%EF%BF%BDZO%02
This is definitely not what I put into the query string. When looking at it, the first time it messes up is %EF(starts 11th character into the original query string). Instead of %EF it shows: %EF%BF%BD. When I searched a little, I found this webpage which says the "Hex UTF-8 Bytes" are EF BF BD.
EDIT:
Forgot to mention, QueryString looks like this:
token=%c9%90%04L%ef%bf%bdEA%ef%bf%bdU%ef%bf%bdi%ef%bf%bdc%3a%ef%bf%bd%ef%bf%bd%40Q%ef%bf%bd%1bn%ef%bf%bd%c3%b5%0fT%ef%bf%bd%ef%bf%bdh%ef%bf%bdm%ef%bf%bd%24tB%ef%bf%bd%ef%bf%bd%08%3b%ef%bf%bd%ef%bf%bd%ef%bf%bd%1b%ef%bf%bdZo%02&oauth_token_secret=S%23%2bw%ef%bf%bd%ef%bf%bdX%17%ef%bf%bd0%ef%bf%bd%60%ef%bf%bd%ef%bf%bd%ef%bf%bd%ef%bf%bd*%ef%bf%bdi%08%ef%bf%bd%ef%bf%bd%ef%bf%bd%ef%bf%bd%07%ef%bf%bd%12RS07%ef%bf%bdgl%1e%ef%bf%bd%d7%832%d1%a1%ef%bf%bd%275%ef%bf%bdv%ef%bf%bd

You might be looking for the HttpServerUtility.UrlDecode method:
HttpContext.Current.Server.UrlDecode(HttpContext.Current.Request.QueryString["token"]);

Your error is somewhere else...
I created a new web page in a .Net 4.0 project, and put this in the Page_Load:
protected void Page_Load(object sender, EventArgs e)
{
var queryString = HttpContext.Current.Request.QueryString;
var token = queryString["token"];
throw new Exception(token);
}
Then I ran the page by going to this URL which matches the querystring you gave above:
http://localhost:27151/test.aspx?token=%c9%90%04L%ef%bf%bdEA%ef%bf%bdU%ef%bf%bdi%ef%bf%bdc%3a%ef%bf%bd%ef%bf%bd%40Q%ef%bf%bd%1bn%ef%bf%bd%c3%b5%0fT%ef%bf%bd%ef%bf%bdh%ef%bf%bdm%ef%bf%bd%24tB%ef%bf%bd%ef%bf%bd%08%3b%ef%bf%bd%ef%bf%bd%ef%bf%bd%1b%ef%bf%bdZo%02
The page decoded the token and displayed it in the exception message as this:
ɐL�EA�U�i�c:��#Q�n�õT��h�m�$tB��;����Zo
(The URL is encoding a binary string so when the actual string is printed, there are some characters that don't get displayed.)
If you run this and the token actually prints "%C9%90%04L..." then your token has probably been double encoded. All of the percent signs will be replaced with "%25" so your URL would look like this:
http://localhost:27151/test.aspx?token=%25c9%2590%2504L%25ef%25bf%25bdEA%25ef%25bf%25bdU%25ef%25bf%25bdi%25ef%25bf%25bdc%253a%25ef%25bf%25bd%25ef%25bf%25bd%2540Q%25ef%25bf%25bd%251bn%25ef%25bf%25bd%25c3%25b5%250fT%25ef%25bf%25bd%25ef%25bf%25bdh%25ef%25bf%25bdm%25ef%25bf%25bd%2524tB%25ef%25bf%25bd%25ef%25bf%25bd......
Since you didn't mention the "%25", the error is somewhere else in your code. The URL you think you are using is not the one being decoded.

Related

QueryString Out of Encoded URL

I have an encoded URL.
http%3a%2f%myurl.test.me%2fSometjing%2fProduct%2fSearch%3fq=Tomato
I am trying to get query string out of the url which is "Tomato". I am using the following code but it returns null.
var parsedQuery = HttpUtility.ParseQueryString((url));
Console.Write(parsedQuery["q"]); // null
You're missing a few steps. You need to decode the URL, then pull out the query string, and then parse the query string:
string decoded =
HttpUtility.UrlDecode("http%3a%2f%2fmyurl.test.me%2fSometjing%2fProduct%2fSearch%3fq=Tomato");
var uri = new Uri(decoded);
var parsedQuery = HttpUtility.ParseQueryString(uri.Query);
Console.WriteLine (parsedQuery["q"]); // Tomato
Also, your encoded URL is a little malformed. The one in your post decoded looks like this:
http:/%myurl.test.me/Sometjing/Product/Search?q=Tomato
I think you just missed a 2f after the % right before myurl.test:
http%3a%2f%2fmyurl.test.me%2fSometjing%2fProduct%2fSearch%3fq=Tomato
The URL needs to decoded first before you can use the HttpUtility.ParseQueryString().
Fair warning though mentioned directly from MSDN.
The ParseQueryString method uses query strings that might contain user input, which is a potential security threat. By default, ASP.NET Web pages validate that user input does not include script or HTML elements. MSDN.

How do I send a URL with Query Strings as a Query String

I am doing a redirect from one page to another and another redirect from the second page to a third. I have imformation from the first page which is not used on the second page but must be transfered to the third page. Is it possible to send the URL of the third page with its Query Strings as a Query String to the second page. Here's an example:
Response.Redirect("MyURL1?redi=MyURL2?name=me&ID=123");
My problem is that the URL being sent as a Query String has two Query String variables, so how will the system know that what's after the & is the second variable of the second URL and not a second variable of the first URL? Thank you.
You must encode the url that you pass as a parameter in your redirect URL. Like this:
MyURL = "MyURL1?redi=" + Server.UrlEncode("MyURL2?name=me&ID=123");
This will create a correct url without the double '?' and '&' characters:
MyURL1?redi=MyURL2%3fname%3dme%26ID%3d123
See MSDN: HttpServerUtility.UrlEncode Method
To extract your redirect url from this encoded url you must use HttpServerUtility.UrlDecode to turn it into a correct url again.
Your query string should look like this:
MyURL1?redi=MyURL2&name=me&ID=123
Check: http://en.wikipedia.org/wiki/Query_string
You should have one ? sign and all parameters joined with &. If parameter values contain special characters just UrlEncode them.
I find it helpful to encode query string parameters in Base64 before sending. In some cases this helps, when you need to send all kinds of special characters. It doesn't make for good debug strings, but it will protect ANYTHING you are sending from getting mixed with any other parameters.
Just keep in mind, the other side who is parsing the query string will also need to parse the Base64 to access the original input.
using System.IO;
using System.Net;
static void sendParam()
{
// Initialise new WebClient object to send request
var client = new WebClient();
// Add the QueryString parameters as Name Value Collections
// that need to go with the HTTP request, the data being sent
client.QueryString.Add("id", "1");
client.QueryString.Add("author", "Amin Malakoti Khah");
client.QueryString.Add("tag", "Programming");
// Prepare the URL to send the request to
string url = "http://026sms.ir/getparam.aspx";
// Send the request and read the response
var stream = client.OpenRead(url);
var reader = new StreamReader(stream);
var response = reader.ReadToEnd().Trim();
// Clean up the stream and HTTP connection
stream.Close();
reader.Close();
}

How to read the query string when it contains unencoded data?

I have the below asp.net page which accepts a "url" query string key whose value can be an un-encoded url:
http://localhost:4104/WebSiteForTest/TinyUrl.aspx?url=http://www.google.co.uk/#hl=en&q=life&oq=life&aq=f&aqi=g-s1g9&aql=&gs_sm=3&gs_upl=2803373l2803701l2l2803826l4l4l0l0l0l0l188l453l0.3l3l0&bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&fp=94681dc4659502d1&biw=1680&bih=883
Now from this page, how would that be possible to read the text after ".aspx?"?
I checked the Request.Url.AbsoluteUri property and it only showed
"http://localhost:4104/WebSiteForTest/TinyUrl.aspx?url=http://www.google.co.uk/"
I also checked with the Request.QueryString with the below code:
private void getQueryString()
{
var sb = new StringBuilder();
var queryStringCount = Request.QueryString.Keys.Count;
for (int keyIndex = 0; keyIndex < queryStringCount; keyIndex++)
{
sb.Append(Request.QueryString.Keys[keyIndex]).Append("=").Append(Request.QueryString[keyIndex]);
if (keyIndex != (queryStringCount - 1))
{
sb.Append("&");
}
}
}
However, the code after "#" doesn't appear in any query string.
how would that be possible to read the text after ".aspx?"?
if you say it's not possible, how Google uses "#" in their url then when you search for something?!
http://www.google.co.uk/#hl=en&site=&q=life&oq=life&aq=f&aqi=g-s1g9&aql=&gs_sm=3&gs_upl=3317l3630l0l3755l4l4l0l0l0l0l125l391l3.1l4l0&bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&fp=94681dc4659502d1&biw=1680&bih=849
Thanks,
It's not possible to get value after anchor on server side, you can check this with fiddler or something similar, you should deal with this on client. Browser simply strips all after anchor.
Retrieving Anchor Link In URL for ASP.Net
c# get complete URL with "#"
Update:
I don't know how google exactly do this, but if you look with fiddler after initial request there goes another without #, here is a fidller log for request from your question :
so my advice is look with fiddler how google do this, or maybe ask another question
Use Request.QueryString
http://localhost:4104/WebSiteForTest/TinyUrl.aspx?url=http://www.google.co.uk/#hl=en&q=life&oq=life&aq=f&aqi=g-s1g9&aql=&gs_sm=3&gs_upl=2803373l2803701l2l2803826l4l4l0l0l0l0l188l453l0.3l3l0&bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&fp=94681dc4659502d1&biw=1680&bih=883
<%=Request.QueryString("url")%> will get the ?url parameter
I assume you're using C# to do this. You can easily get the parameters and their values by iterating through the request object. Or in this case, since you know the name of the parameter, simply do this:
String url = Request.QueryString["url"];
More information on iterating through your request parameters can be found here.
The Uri Type works as well.
String yourHttpUri ="....";
Uri yourURI = new Uri(yourHttpUri);
yourURI.query // "?url=http://www.google.co.uk/"
yourURI.fragment // "#hl=en&q=life&oq=life&aq=f&aqi=g-s1g9&aql=&gs_sm=3&gs_upl=2803373l2803701l2l2803826l4l4l0l0l0l0l188l453l0.3l3l0&bav=on.2,or.r_gc.r_pw.r_cp.,cf.osb&fp=94681dc4659502d1&biw=1680&bih=883"
Edit:
Have you tried Request.Url.ToString(); (And create a new Uri from the result)

WebBrowser keep url/uri encoded dont decode

I have a web-browser in a win form application and I am experiencing issues when opening a URL.
The URL I pass in as a new URL instance is encoded with:
/ as %2f , ? as %3f and the
= as %3d
But when I debug my code I can see that the absolute URL or any of the other ones in the webbrowser.url.* is decoded as / , ? and =.
How do I keep the URL encoded? The URL will not work if It is not encoded like that.
I found a solution to my problem, when you have a URL that looks something like this:
domain.com/action/doaction/?identity=12354698789
And you want it encoded like this:
domain.com/logon?returnurl=action%2fdoaction%2f%3fidentity%3d12354698789
That does not work in your web browser. It decodes it to the first url.
I needed the id in the doaction controller so I used this code:
string orgId = ControllerContext.RouteData.Values["id"].ToString();
It returns that url, if unsure, debug and trace through, you will find the right key and value.
Why is it a problem?
If you want the undecoded URL, use the HttpRequest.RawUrl Property. The query string is automatically decoded by default and there is no public parameter that would turn it off.

Broken encoding after postback

I have a query string with a parameter value that contains the norwegian character å encoded as %e5. The page contains a form with an action attribute which is automatically filled by ASP.Net. When the URL is output into said attribute it is printed with a full two byte encoding: %u00e5.
When posting back this seems to be ok when debugging the code behind. However the page actually does a redirect to itself (for some other reason) and the redirect location header looks like this: Location: /myFolder/MyPage.aspx?Param1=%C3%A5
So the %e5 has been translated to %C3%A5 which breaks the output somehow.
In HTML text the broken characters look like å after having been output via HttpUtility.HtmlEncode.
The entire web application is ISO8859-1 encoded.
PS. When removing the u00 from the output %u00e5 in the action attribute before posting the form, everything is output nicely. But the error seems to be the translation from %e5 to %C3%A5. (And of course the self redirect, but that's another matter.)
Any pointers?
The solution I ended up with was encoding the redirect URL manually.
public void ReloadPage()
{
UrlBuilder url = new UrlBuilder(Context, Request.Path);
foreach (string queryParam in Request.QueryString.AllKeys)
{
string queryParamValue = Request.QueryString[queryParam];
url.AddQueryItem(queryParam, queryParamValue);
}
Response.Redirect( url.ToString(), true);
}
The url.AddQueryItem basically does HttpContext.Server.UrlDecode(queryParamValue) and the url.ToString builds the query string and for each query item does HttpContext.Server.UrlEncode( queryParamValue).
The UrlBuilder is a class already present in our library, so once I found the problem and realized that C#/.Net didn't provide tools for this, coding the fix was quick :)

Categories