18

開発マシンにVS2012Premiumをインストールした後、単体テストが失敗したため、開発者は問題を修正しました。変更がTeamCityにプッシュされたとき、単体テストは失敗しました。プロジェクトは、VS2012と互換性があるようにアップグレードされているソリューションファイル以外は変更されていません。それはまだ.netフレームワーク4.0を対象としています

を呼び出すときにUnicode文字がエスケープされる問題に問題を切り分けましたUri.ToString。次のコードは、動作を複製します。

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でこれを実行すると失敗します。どちらも、NuGetの最新バージョンのNCrunchとNUnitを使用しています。

VS2012がインストールされていないマシン

VS2012がインストールされているマシン

失敗したアサートからのメッセージは次のとおりです。

  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"
  -----------------------------------------------------^

.NET4と.NET4.5の両方に関するMSDNのドキュメントにはToString、この文字をエンコードしてはならないことが示されています。つまり、古い動作が正しい動作である必要があります。

A String instance that contains the unescaped canonical representation of the Uri instance. All characters are unescaped except #, ?, and %.

VS2012をインストールした後、そのユニコード文字はエスケープされています。

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

    }
}

少し詳しく調べてみましょう。.NET4.0または.NET4.5をターゲットにするとテストは失敗し、.NET3.5に切り替えると成功します。

4

3 に答える 3

8

VS2012 と共にインストールされる .NET Framework 4.5 にはいくつかの変更が導入されており、(私の知る限りでは) いわゆる「インプレース アップグレード」でもあります。これは、実際に .NET Framework 4 をアップグレードすることを意味します。

さらに、System.Uri に文書化された重大な変更があります。それらの 1 つは、Unicode 正規化フォーム C (NFC) が URI の非ホスト部分で実行されなくなると述べています。これがあなたのケースに当てはまるかどうかはわかりませんが、エラーの調査の出発点として役立つ可能性があります.

于 2012-08-22T06:16:50.937 に答える
6

この変更は、以前の.NETバージョンの問題に関連しており、現在は標準に準拠するように変更されています。%B6はUTF-16ですが、標準によれば、UTF-8をUriで使用する必要があります。つまり、UTF-8を使用する必要があります%C2%B6。したがって、%B6UTF-8ではないため、正しく無視され、デコードされなくなりました。

以下に逐語的に引用されている接続レポートからの詳細。

.NET 4.5は、URIのIRI解析ルールをサポートするRFC3987の拡張されたより互換性のあるアプリケーションを備えています。IRIはInternationalResourceIdentifiersです。これにより、非ASCII文字をURI/IRI文字列に含めることができます。

.NET 4.5より前は、IRIの処理に一貫性がありませんでした。デフォルトがfalseのapp.configエントリがあり、これをオンにできます。

これは、IRIの処理/解析を行いました。しかし、いくつか問題がありました。特に、誤ったパーセントエンコーディング処理が可能になりました。URI / IRI文字列内のパーセントエンコードされたアイテムは、RFC 3987に従ってパーセントエンコードされたUTF-8オクテットであると想定されています。これらは、パーセントエンコードされたUTF-16としては解釈されません。したがって、UTF-8によると、「%B6」の処理は正しくなく、デコードは行われません。¶の正しいUTF-8エンコーディングは、実際には「%C2%B6」です。

代わりに文字列がこれだった場合:

        string strUri = @"http://www.example.com/test?helloworld=foo%C2%B6bar";

次に、ToString()メソッドで正規化され、パーセントエンコードがデコードされて削除されます。

アプリケーションのニーズとToString()メソッドの使用に関する詳細情報を提供できますか?通常、ほとんどの正規化のニーズには、UriオブジェクトのAbsoluteUriプロパティをお勧めします。

この問題がアプリケーション開発とビジネスニーズを妨げている場合は、「netfx45compat atMicrosoftdotcom」の電子メールアドレスでお知らせください。

どうも、

ネットワーキングチーム

于 2012-09-11T09:09:55.807 に答える
0

その状況では、あなたはそのようにすることはできません。主な問題は文字「¶」です。

.Net では、文字 ¶ で問題が発生しました。その上で調査を行うことができます。

uri' パラメータを 1 つずつ取得します。1つずつ足して比べてみてください。「¶」文字のメソッドを使用して作成または置換できる場合があります。

例えば;

Dim uri = New Uri("http://www.example.org/test?helloworld=foo%B6bar")

Assert.AreEqual("http://www.example.org/test?helloworld=foo¶bar", uri.Host+uri.AbsolutePath+"?"+uri.Query)

それはうまくいく

uri.AbsolutePath: /test

url.ホスト: http://www.example.org

uri.Query: helloworld=foo¶bar

于 2012-08-17T12:04:40.427 に答える