Is QueryString really case insensitive?
I am working on a payment platform and in response to the payment, a simple GET call is received in my listener with some parameters in the query string:
http:? // localhost / mytest / listener TIMECREATED = 04.08.2015 + 12% 3A22% 3A27 & statoattuale = the OK & PREVIOUSSTATE = the IN & CurrentState = payment_approved & tipomessaggio = PAYMENT_STATE & Descrizione = CAMBIO + the DI + stato & datacreazione = 04/08/2015 + 12% 3A22% 3A27 & Stabilimento = XXXXXX & MerchantNumber = XXXXXX & Descrizione = CAMBIO + DI + Stato & OBJECT = PAYMENT & TimeGenerated = 08/04/2015 + 12% 3A23% 3A17 & MERCHANTNUMBER = XXXXXX & statopreceXXCommerte = & MERCHANTACXCOUNT = XXXOnumer & datagenerazione = 08/04/2015 + 12% 3A23% 3A17 & ORDERNUMBER = myOrderNo & Stabilimento = XXXXXX &Mac = CaWJiRCxbWH% 2FsNFMvHUD2A% 3D% 3D &MAC = AnsEvRHkvMwRL% 2FgehVtnhA% 3D% 3D
When I check Request.QueryString
what I am getting it is a mess in order and param case. It looks like they are reordered with an adjusted case for the first appearance. Like this:
TIMECREATED = 08/04/2015 12: 22: 27 & statoattuale = OK & PREVIOUSSTATE = B & CurrentState = payment_approved & tipomessaggio = PAYMENT_STATE & Descrizione = CAMBIO DI STATO & DESCRIZIONE = CAMBIO DI STATO & datacreazione = 08/04/2015 12: 22nd datacreazione = 08/04/2015 Stabilimento = XXXXXX & Stabilimento = XXXXXX & MerchantNumber = XXXXXX & MerchantNumber = XXXXXX & OBJECT = PAYMENT & TimeGenerated = 08/04/2015 12: 23: 17 & statoprecedente = B & MERCHANTACCOUNT = 999988rdine & datOnumeX .2015 12: 23: 17 & ORDERNUMBER = myOrderNo &Mac = CaWJiRCxbWH / sNFMvHUD2A == & Mac= AnsEvRHkvMwRL / gehVtnhA ==
This looks like a bug to me because RFC3986 says:
When a URI uses common syntax components, the syntactic equivalence rule component always applies; namely that schema and host are case insensitive and therefore must be normalized to lower case. For example, URI is equivalent to http://www.example.com/ . Other common syntax components are considered <strong> case sensitive unless otherwise specified by the schema (see section 6.2.3).
At the moment I solved my problem by manually disassembling it Url.Query
, but I still don't think the correct behavior of Request.QueryString is.
Can someone shed some light on this question?
source to share
Unfortunately, the API does not provide a way to make a collection case Request.QueryString
sensitive (or collection Request.Headers
or Request.Form
for that matter).
However, with a little bit of reverse engineering through reflection, it's not that hard to do.
public class CaseSensitiveQueryStringCollection : System.Collections.Specialized.NameValueCollection
{
public CaseSensitiveQueryStringCollection(string queryString, bool urlencoded, System.Text.Encoding encoding)
// This makes it case sensitive, the default is StringComparer.OrdinalIgnoreCase
: base(StringComparer.Ordinal)
{
if (queryString.StartsWith("?"))
{
queryString = queryString.Substring(1);
}
this.FillFromString(queryString, urlencoded, encoding);
}
internal void FillFromString(string s, bool urlencoded, System.Text.Encoding encoding)
{
int num = (s != null) ? s.Length : 0;
for (int i = 0; i < num; i++)
{
int startIndex = i;
int num4 = -1;
while (i < num)
{
char ch = s[i];
if (ch == '=')
{
if (num4 < 0)
{
num4 = i;
}
}
else if (ch == '&')
{
break;
}
i++;
}
string str = null;
string str2 = null;
if (num4 >= 0)
{
str = s.Substring(startIndex, num4 - startIndex);
str2 = s.Substring(num4 + 1, (i - num4) - 1);
}
else
{
str2 = s.Substring(startIndex, i - startIndex);
}
if (urlencoded)
{
base.Add(HttpUtility.UrlDecode(str, encoding), HttpUtility.UrlDecode(str2, encoding));
}
else
{
base.Add(str, str2);
}
if ((i == (num - 1)) && (s[i] == '&'))
{
base.Add(null, string.Empty);
}
}
}
}
Using
var query = new CaseSensitiveQueryStringCollection(
HttpContext.Current.Request.Url.Query,
true,
System.Text.Encoding.UTF8);
When you use query type ?MAC=123&mac=456
, you can see that they are stored separately.
source to share