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?

+3


source to share


1 answer


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.

+1


source







All Articles