在开发机器上安装VS2012 Premium后,单元测试失败,因此开发人员修复了该问题。当更改被推送到TeamCity时,单元测试失败。除了升级的解决方案文件与VS2012兼容之外,项目没有改变。它仍然以.net framework 4.0为目标
我已将问题隔离到调用Uri.ToString
时转义unicode字符的问题。以下代码复制了该行为。
Imports NUnit.Framework
<TestFixture()>
Public Class UriTest
<Test()>
Public Sub UriToStringUrlDecodes()
Dim uri = New Uri("http://www.example.org/test?helloworld=foo%B6bar")
Assert.AreEqual("http://www.example.org/test?helloworld=foo¶bar", uri.ToString())
End Sub
End Class
在没有安装VS2012的计算机上在VS2010中运行此功能成功,在安装了VS2012的计算机上的VS2010中运行此功能失败。两者都使用最新版本的NCrunch和NuGet的NUnit。
来自失败断言的消息是
Expected string length 46 but was 48. Strings differ at index 42.
Expected: "http://www.example.org/test?helloworld=foo¶bar"
But was: "http://www.example.org/test?helloworld=foo%B6bar"
-----------------------------------------------------^
.NET 4和.NET 4.5的MSDN文档显示ToString
不应对此字符进行编码,这意味着旧行为应该是正确的。
A String instance that contains the unescaped canonical representation of the Uri instance. All characters are unescaped except #, ?, and %.
安装VS2012后,正在转义该unicode字符。
VS2012计算机上System.dll的文件版本为4.0.30319.17929
构建服务器上的System.dll的文件版本是4.0.30319.236
忽略我们使用uri.ToString()
的原因,我们正在测试的内容以及任何潜在的解决方案。任何人都可以解释为什么这种行为似乎已经改变,或者这是一个错误?
编辑,这是C#版本
using System;
using NUnit.Framework;
namespace SystemUriCSharp
{
[TestFixture]
public class UriTest
{
[Test]
public void UriToStringDoesNotEscapeUnicodeCharacters()
{
var uri = new Uri(@"http://www.example.org/test?helloworld=foo%B6bar");
Assert.AreEqual(@"http://www.example.org/test?helloworld=foo¶bar", uri.ToString());
}
}
}
进一步调查,如果我以.NET 4.0或.NET 4.5为目标,测试失败,如果我将其切换到.NET 3.5,那么它就会成功。
答案 0 :(得分:8)
.NET Framework 4.5中引入了一些更改,它与VS2012一起安装,并且(据我所知)也称为“就地升级”。这意味着它实际上升级了.NET Framework 4。
此外,还有breaking changes documented in System.Uri。其中一个说 Unicode规范化形式C(NFC)将不再在URI的非主机部分上执行。我不确定这是否适用于您的情况,但它可以作为您调查错误的良好起点。
答案 1 :(得分:6)
此更改与早期.NET版本的问题有关,现在已更改为更符合标准。 %B6
是UTF-16,但根据标准,UTF-8应该在Uri中使用,这意味着它应该是%C2%B6
。因此%B6
不是UTF-8,现在它被正确忽略而不被解码。
以下逐字引用的connect report更多详情。
.NET 4.5具有增强且更兼容的RFC 3987应用程序 它支持URI的IRI解析规则。 IRI是国际性的 资源标识符。这允许非ASCII字符在a中 要解析的URI / IRI字符串。
在.NET 4.5之前,我们对IRI进行了一些不一致的处理。我们有 您可以打开的默认值为false的app.config条目:
进行了一些IRI处理/解析。但是,它有一些问题。在 特别是它允许不正确的百分比编码处理。 应该是URI / IRI字符串中的百分比编码项 根据RFC 3987,百分比编码的UTF-8八位字节。它们不是 解释为百分比编码的UTF-16。因此,处理“%B6”是不正确的 根据UTF-8,不会发生解码。正确的UTF-8 ¶的编码实际上是“%C2%B6”。
如果您的字符串是这样的话:
string strUri = @"http://www.example.com/test?helloworld=foo%C2%B6bar";
然后它将在ToString()方法中得到规范化 百分比编码解码并删除。
您能否提供有关您的应用程序需求的更多信息? 使用ToString()方法?通常,我们推荐AbsoluteUri Uri对象的属性,用于大多数规范化需求。
如果此问题阻碍了您的应用程序开发和业务 需要请通过Microsoft dot的netfx45compat告诉我们 com“电子邮件地址。
THX,
网络团队