2012-08-17 30 views
18

Sau khi cài đặt VS2012 Premium trên máy dev, kiểm tra đơn vị không thành công, vì vậy nhà phát triển đã khắc phục vấn đề. Khi các thay đổi được đẩy vào TeamCity, kiểm tra đơn vị không thành công. Dự án đã không thay đổi khác với tệp giải pháp đang được nâng cấp để tương thích với VS2012. Nó vẫn nhắm mục tiêu .net framework 4.0Thay đổi hành vi của hệ thống.Uri.ToString sau khi cài đặt VS2012

Tôi đã tách sự cố xảy ra với các ký tự unicode bị thoát khi gọi Uri.ToString. Mã sau đây sao chép hành vi.

Chạy trong VS2010 trên máy chưa cài đặt VS2012 thành công, chạy trong VS2010 trên máy có cài đặt VS2012 không thành công. Cả hai đều sử dụng phiên bản mới nhất của NCrunch và NUnit từ NuGet.

Machine without VS2012 Install

Machine with VS2012 Install

Các thông điệp từ khẳng định thất bại là

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

Các tài liệu trên MSDN cho cả .NET 4 và .NET 4.5 cho thấy ToString không nên mã hóa nhân vật này, có nghĩa là hành vi cũ phải là hành vi đúng.

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

Sau khi cài đặt VS2012, ký tự unicode đó sẽ bị thoát.

Phiên bản tập tin của System.dll trên máy với VS2012 là 4.0.30319.17929

Phiên bản tập tin của System.dll trên máy chủ xây dựng là 4.0.30319.236

Lờ đi những giá trị của lý do tại sao chúng tôi sử dụng uri.ToString(), những gì chúng tôi đang thử nghiệm và mọi công việc tiềm năng xung quanh. Bất cứ ai có thể giải thích lý do tại sao hành vi này dường như đã thay đổi, hoặc là một lỗi này?

Chỉnh sửa, đây là phiên bản 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()); 
     } 

    } 
} 

Một chút điều tra thêm, nếu tôi nhắm mục tiêu NET 4.0 hoặc .NET 4.5 các cuộc thử nghiệm thất bại, nếu tôi chuyển đổi nó để NET 3.5 thì nó thành công.

+0

Tôi biết rằng logic mệnh lệnh mà tôi đang làm một cái gì đó sai và sẽ không có một lỗi trong .NET, nhưng tôi chỉ không thể làm việc tại sao điều này xảy ra. –

+0

Có lẽ là "bool check = @" http://www.example.org/test?helloworld=foo¶bar "== uri.ToString();' là sai, phải không? – t3hn00b

+0

Có đó là sai –

Trả lời

6

Thay đổi có liên quan đến các sự cố với phiên bản .NET cũ hơn, hiện đã thay đổi để tuân thủ các tiêu chuẩn. %B6 là UTF-16, nhưng theo các tiêu chuẩn UTF-8 nên được sử dụng trong Uri, có nghĩa là nó phải là %C2%B6. Vì vậy, như %B6 không phải là UTF-8 nó bây giờ được bỏ qua một cách chính xác và không được giải mã.

Chi tiết khác từ số connect report được trích dẫn ở nguyên văn bên dưới.

.NET 4.5 có ứng dụng nâng cao và tương thích hơn RFC 3987 hỗ trợ quy tắc phân tích cú pháp IRI cho URI. IRI là quốc tế Mã định danh tài nguyên. Điều này cho phép các ký tự không phải ASCII nằm trong một chuỗi URI/IRI được phân tích cú pháp.

Trước .NET 4.5, chúng tôi đã xử lý các IRI không nhất quán. Chúng tôi đã có mục nhập app.config có mặc định là sai mà bạn có thể bật:

đã xử lý/phân tích cú pháp IRI. Tuy nhiên, nó có một số vấn đề. Trong cụ thể nó được phép xử lý mã hóa phần trăm không chính xác. Các mục được mã hóa phần trăm trong chuỗi URI/IRI được coi là octet UTF-8 được mã hóa theo phần trăm theo RFC 3987. Chúng không phải là được hiểu là mã UTF-16 được mã hóa theo phần trăm. Vì vậy, xử lý “% B6” là không chính xác theo UTF-8 và không giải mã sẽ xảy ra. Mã hóa UTF-8 đúng cho ¶ thực ra là “% C2% B6”.

Nếu chuỗi của bạn là này thay vì:

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

Sau đó, nó sẽ nhận được bình thường trong phương thức ToString() và trăm mã hóa giải mã và loại bỏ.

Bạn có thể cung cấp thêm thông tin về nhu cầu ứng dụng của mình và sử dụng phương thức ToString() không? Thông thường, chúng tôi khuyên bạn nên sử dụng thuộc tính AbsoluteUri của đối tượng Uri cho hầu hết các nhu cầu bình thường hóa.

Nếu sự cố này đang chặn phát triển ứng dụng và doanh nghiệp của bạn thì hãy cho chúng tôi biết qua địa chỉ email "netfx45compat at Microsoft dot com".

Thx,

Mạng Đội

0

Trong trường hợp đó, bạn không thể làm như vậy. Vấn đề chính là ký tự "¶".

Trong .Net, chúng tôi gặp sự cố về ký tự ¶. Bạn có thể thực hiện một nghiên cứu về điều đó.

Thu thập thông số của từng người một. Thêm từng cái một và so sánh chúng. Có thể bạn có thể sử dụng phương thức cho ký tự "¶" để tạo hoặc thay thế nó.

Ví dụ;

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) 

rằng tôi sẽ làm việc

uri.AbsolutePath:/kiểm tra

url.Host: http://www.example.org

uri.Query: helloworld = foo¶bar

+0

Nó hoạt động trước khi tôi cài đặt VS2012 và sẽ hoạt động theo tài liệu MSDN. Tôi không thú vị trong một công việc xung quanh - đó là đơn giản, tôi quan tâm nó tại sao nó không còn hoạt động. –

8

Có một số thay đổi được giới thiệu trong .NET Framework 4.5, được cài đặt cùng với VS2012, và đó cũng là (theo sự hiểu biết của tôi) một cái gọi là "nâng cấp vị trí". Điều này có nghĩa là nó thực sự nâng cấp .NET Framework 4.

Hơn nữa, có breaking changes documented in System.Uri. Một trong số họ cho biết biểu mẫu chuẩn hóa Unicode C (NFC) sẽ không còn được thực hiện trên các phần không lưu trữ của URI. Tôi không chắc liệu điều này có thể áp dụng cho trường hợp của bạn hay không, nhưng nó có thể là điểm khởi đầu tốt trong việc điều tra lỗi của bạn.

+0

Thú vị, nó giải thích lý do tại sao nó thay đổi - nó có thể là một tác dụng phụ của một trong những thay đổi phá vỡ, tôi đã hy vọng sẽ nhận được một phản ứng thông qua kết nối ngay bây giờ nhưng không có may mắn. –

+0

Tại chỗ tốt, tuy nhiên nó nói rằng "Điều này chỉ ảnh hưởng đến các ứng dụng nhắm mục tiêu Khuôn khổ .NET 4.5." – Justin

Các vấn đề liên quan