Best way to check for upper/lower case query strings
Asked Answered
S

3

7

I have a problem where I need to extract a query string parameter from a url. The parameter could be either "Territory" or "territory" or other upper/lower case variations of that word. Although the following works for the first two cases I wonder if there is a better way?

IDictionary<string, string> queryString = HtmlPage.Document.QueryString;

if (queryString.ContainsKey("territory"))
{
    ish.SetDefaultRegion(int.Parse(queryString["territory"]));
    // do something (the same something as below)
}
else if (queryString.ContainsKey("Territory"))
{
    ish.SetDefaultRegion(int.Parse(queryString["Territory"]));
    // do something (the same something as above)
}

I would prefer to insert the query string into the dictionary ignoring case (ie. if the user accidentally typed "TERRITORY" this code would fail, so how can I just test that the word exists regardless of casing?

Salome answered 3/5, 2012 at 16:54 Comment(7)
This could help you out. Get the key from the queryString object. Convert it into small case and then compare with "territory". This way you wouldnt have to worry about the casing.Orthogenic
@Krishna: And how exactly can the key be obtained from the queryString object, if you don't know its case (besides iterating through every key)?Jataka
@Jataka - Thank you for clarifying. That's exactly my issue!Salome
Request.QueryString["territory"] is already case-insensitive. It doesn't matter whether it's in the URL as "Territory", "territory", "TeRrItOrY", etc.Marozik
@Doug That may well be true but ContainsKey lookup will still fail to match "Territory" and "TeRrItOrY" - hence why, as per the answer, when creating the Dictionary from the QueryString, a case-insensitive key comparer is needed.Salome
@rmcsharry: Why do you need to convert the Request.QueryString object to a Dictionary? If you want to know if a key exists in the QueryString object, just do if (Request.QueryString["TeRriToRy"] != null) {Marozik
The key is user generated, it can therefore be any mix of lower case or upper case. Doing as you suggested will only return true if the casing is exactly as you typed it. Therefore the QueryString needs to be converted to a Dictionary and case-insensitive key comparer used to match all variations of casing that the use might type. And since QueryString is itself a dictionary you cannot simply call toLower on it.Salome
J
14

Use a dictionary with a case-insensitive key comparer:

var queryParams = new Dictionary<string, string>(
    HtmlPage.Document.QueryString,
    StringComparer.InvariantCultureIgnoreCase
);

if (queryParams.ContainsKey("territory")) {
    // Covers "territory", "Territory", "teRRitory", etc.
}
Jataka answered 3/5, 2012 at 16:58 Comment(2)
Warning: i believe InvariantCultureIgnoreCase is a dangerous choice. it seems OrdinalIgnoreCase is the safe choice. It is my understanding that InvariantCulture treats accentented letters as the same as non accented letters. so i interpret this means 'resumeID' = 'resuméID'. but i understand that OrdinalIgnoreCase treats 'resumeID' and 'resuméID' as different strings. Disclaimer: I have not tested this and don't have the time to do so at this time. Much info on the net is bad advice or just flat wrong, so i'm only posting this a 'be careful of this' and i don't know for sure. :PDiarchy
@Shawn: You know, OrdinalIgnoreCase is probably a better default here. But, InvariantCultureIgnoreCase certainly does not consider resumeID and resuméID to be equal (try it!). I believe it merely does a form of Unicode normalization during the comparison (so, e followed by a combining acute accent would equal the e-with-acute-accent character), whereas OrdinalIgnoreCase checks codepoint by codepoint (though I may be wrong too, heh). There's some more info here.Jataka
S
2

If your QueryString Object is not a dictionary object but instead is something such as a NameValueCollection...

IDictionary<string, string> queryString = QueryString.AllKeys.ToDictionary(k => k.ToLowerInvariant(), k => QueryString[k]);
Steinmetz answered 7/1, 2014 at 19:3 Comment(1)
but wud this code break (error) when the querystring contains 'duplicate' keys that only differ in case? So what does this code do when the querystring is 'abc=1&ABC=2'?Diarchy
B
0

Hello it can be also TeRriTory, in the querystring do a .Tolower()

Balladmonger answered 3/5, 2012 at 16:59 Comment(1)
Querystring is a dictionary, you cannot do a tolower on itSalome

© 2022 - 2024 — McMap. All rights reserved.