C# QueryString真的不区分大小写吗?

C# QueryString真的不区分大小写吗?,c#,asp.net-mvc,asp.net-mvc-5,C#,Asp.net Mvc,Asp.net Mvc 5,我在一个支付平台上工作,为了响应支付,向我的侦听器发出了一个简单的GET调用,查询字符串中有一些参数: descripione=CAMBIO+DI+STATO&datacreazione=04.08.2015+12%3A22%3A27&stabilityo=xxxxxx&MerchantNumber=xxxxxx&descripione=CAMBIO+DI+STATO&OBJECT=付款和时间生成=04.08.2015+12%3A23%17&MerchantNumber=xxxxxx&stato

我在一个支付平台上工作,为了响应支付,向我的侦听器发出了一个简单的GET调用,查询字符串中有一些参数:

descripione=CAMBIO+DI+STATO&datacreazione=04.08.2015+12%3A22%3A27&stabilityo=xxxxxx&MerchantNumber=xxxxxx&descripione=CAMBIO+DI+STATO&OBJECT=付款和时间生成=04.08.2015+12%3A23%17&MerchantNumber=xxxxxx&statoRecente=IN&MERCHANTACCOUNT=xxxxxx&numeroOrdine=myOrderNo&numeriocommerciate=xxxxxx&datagenerazione=04.08.2015+12%3A23%3A17&ORDERNUMBER=myOrderNo&stabilityo=xxxxxx&mac=CaWJiRCxbWH%2FsNFMvHUD2A%3D&mac=AnsEvRHkvMwRL%2FgehVtnhA%3D%3D%3D%3D

当我检查
Request.QueryString
时,我得到的是参数顺序和大小写的混乱。第一次出现时,它们似乎是按调整后的大小写重新排序的。像这样:

创建时间=2015年8月4日 12:22:27&statoattuale=OK&PREVIOUSSTATE=IN&CURRENTSTATE=payment\u approved&tipomessaggio=payment\u STATE&说明 描述:坎比奥·迪斯塔托和datacreazione=2015年8月4日 12:22:27&稳定o=xxxxxx&稳定o=xxxxxx&商品编号=xxxxxx&=xxxxxx&商品编号=xxxxxx&OBJECT=PAYMENT&TIMEGENERATED=2015年8月4日 12:23:17&StatoReceidente=IN&MERCHANTACCOUNT=99998801&numeroOrdine=myOrderNo&numeroCommerciante=xxxxxx&datagenerazione=04.08.2015 12:23:17&ORDERNUMBER=myOrderNo&mac=CaWJiRCxbWH/sNFMvHUD2A==&mac=AnsEvRHkvMwRL/gehVtnhA==

对我来说,它看起来像一个bug,因为RFC3986声明:

当URI使用通用语法的组件时,组件 语法等价规则始终适用;即计划及 主机不区分大小写,因此应规范化为 小写字母。例如,URI是 相当于。另一种通用语法 除非特别说明,否则假定组件区分大小写 方案另有规定(见第6.2.3节)

目前,我通过手动解析
Url.Query
解决了我的问题,但我仍然不认为how behave Request.QueryString是正确的


有人能解释一下吗?

不幸的是,API没有提供使
请求.QueryString
集合区分大小写的方法(或者
请求.Headers
请求.Form
集合区分大小写)

然而,通过反射进行一点逆向工程并不是那么困难

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);
            }
        }
    }
}

当你使用像
?MAC=123&MAC=456这样的查询字符串时,你可以看到它们是分开的。

你的问题到底是什么<代码>请求。查询字符串不区分大小写。您可以使用
Request.QueryString[“test”]
Request.QueryString[“test”]
,两者都将获得相同的参数值,这就是我的观点。如果您尝试执行
Request.QueryString[“mac”]
,您将得到
CaWJiRCxbWH/sNFMvHUD2A==,AnsEvRHkvMwRL/gehVtnhA=
(两个值都用逗号分隔)以及
Request.QueryString[“mac”
Request.QueryString[“mac”
,您将得到相同的结果。还有,为什么
Request.QueryString
觉得有必要更改参数的顺序和大小写?RFC说,必须将参数视为区分大小写的。那么为什么它不尊重这一点呢?RFC很好。Net让您与之交互的功能是完全不同的。如果你需要严格区分大小写的方法,那么你需要做你所做的。如果有人来这里,因为他们想知道
HttpContext.Request.Query[“foo”]
是否不区分大小写,它与相同的事情相关,因此,是的,它也是。我最终得到了类似的结果,我想理解的是为什么QueryString不代表RFC,我们必须重新发明轮子。很简单,因为微软认为易用性胜过严格遵守。如果您曾经花费数小时试图跟踪一个仅因为字符串(或URL)中的大小写错误而发生的问题,您知道我的意思。但我不明白为什么他们没有让区分大小写比这更容易切换-它应该只是一个配置切换。也许这是创建一个开源项目的一个线索,该项目基于HttpContextBase提供了一个完整的区分大小写的HttpContext,这样每个人都不必为此重新发明轮子。这是一个很好的建议。我想我找到了我的新周末计划:)
var query = new CaseSensitiveQueryStringCollection(
    HttpContext.Current.Request.Url.Query, 
    true, 
    System.Text.Encoding.UTF8);