.NET Core里的UrlEncode之坑

当我们在.NET Core中处理URL编码的时候,有两个API可以选择:System.Net.WebUtility.UrlEncode 和 System.Web.HttpUtility.UrlEncode。他们有什么区别,我们又该选择哪个?我做了一些研究,本文是我的一些发现。

01

测试结果

首先,我们来看看测试。我测试了2对WebUtilityHttpUtility里相同的方法:

UrlEncode/UrlDecode 以及 HtmlEncode/HtmlDecode

唯一有区别的是UrlEncode(string)返回了不同的结果:

var webencode = System.Net.WebUtility.UrlEncode(test);

var httpencode = System.Web.HttpUtility.UrlEncode(test);

Console.WriteLine($"WebUtility.UrlEncode: {webencode}");

Console.WriteLine($"HttpUtility.UrlEncode: {httpencode}");

针对需要被编码的字符,WebUtility.UrlEncode()返回了大写,而HttpUtility.UrlEncode()返回的是小写

02

这TM是怎么回事

感谢微软开源了.NET,我们能够通过查看.NET Core的源代码发现原因,源代码戳这里:https://github.com/dotnet/corefx

如果你想亲眼看看的话,代码路径如下:

WebUtility类

\corefx\src\System.Runtime.Extensions\src\System\Net\WebUtility.cs

HttpUtility类

\corefx\src\System.Web.HttpUtility\src\System\Web\HttpUtility.cs

WebUtility

我在408行找到了UrlEncode方法(行号可能会变,如果微软修改了源代码)

它会调用GetEncodedBytes()方法

而这里面又会调用IntToHex()方法

最终,我们能够发现,因为强转了一个大写字符'A',所以任何被编码的字符都会输出为大写。

HttpUtility

我对HttpUtility做了相同的分析,最终发现它调用了System.Web.Util.IntToHex()方法,代码如下:

这就解释了为啥它返回的总是小写字符。

我的猜想

我不知道这是否为刻意设计的,但有两个版本的IntToHex()方法让我比较懵逼。我更希望API能给调用者提供一个可选参数用来控制输出字符的大小写。

03

那么该选哪个方法呢?

简而言之,我自己的系统里全部使用小写URL。所以我会选择使用HttpUtility.UrlEncode()去编码URL。

在Windows系统里,URL的大小写是无所谓的。但是Linux里是不一样的,大小写不一致可能让你遇到404。而且,大写字符和小写字符的HASH是不一样的,如果你的系统里有某个地方通过HASH来校验URL,那么大小写问题会导致校验失败。

说到SEO的话,有些人可能认为小写是更加SEO友好的,但实际上URL大小写在Google这里是不影响排名的。不信可以看看论坛:

https://productforums.google.com/forum/#!topic/webmasters/ky1L_dj4n5c/discussion (嗯,好像这是个不存在的网站)

关键在于,你需要在自己的系统里保证URL大小写规则一致,并且留意与你的系统对接的其它系统,是否用了不同的URL大小写处理方式。