C# QueryString真的不区分大小写吗?
我在一个支付平台上工作,为了响应支付,向我的侦听器发出了一个简单的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 当我检查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
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);