2012-08-17 11 views
18

Después de instalar VS2012 Premium en una máquina dev falló una prueba de unidad, por lo que el desarrollador solucionó el problema. Cuando los cambios se enviaron a TeamCity, la prueba de la unidad falló. El proyecto no ha cambiado más que el archivo de la solución que se está actualizando para ser compatible con VS2012. Aún se dirige a .NET framework 4.0System.Uri.ToString cambio de comportamiento después de la instalación de VS2012

He aislado el problema de un problema con los caracteres Unicode que se escapan al llamar al Uri.ToString. El siguiente código replica el comportamiento.

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 

La ejecución de este en VS2010 en una máquina que no tenga instalado VS2012 tiene éxito, la ejecución de este en VS2010 en una máquina con VS2012 instalado falla. Ambos usan la última versión de NCrunch y NUnit de NuGet.

Machine without VS2012 Install

Machine with VS2012 Install

Los mensajes de la aserción no son

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

La documentación sobre MSDN tanto para .NET 4 y .NET 4.5 muestra que no hay que codificar ToString este personaje, lo que significa que el comportamiento anterior debería ser el correcto.

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

Después de instalar VS2012, se está escapando ese carácter Unicode.

La versión del archivo de System.dll en la máquina con VS2012 es 4.0.30319.17929

La versión del archivo de System.dll en el servidor de compilación es 4.0.30319.236

Haciendo caso omiso de los méritos de por qué somos usando uri.ToString(), lo que estamos probando y cualquier posible solución alternativa. ¿Alguien puede explicar por qué este comportamiento parece haber cambiado, o es un error?

Editar, aquí está la versió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()); 
     } 

    } 
} 

Un poco de investigación adicional, si me meta .NET 4.0 o .NET 4.5 las pruebas fallan, si me cambio a .NET 3.5, entonces tiene éxito.

+0

Soy consciente de que la lógica dicta que estoy haciendo algo mal y no habrá un error en .NET, pero simplemente no puedo trabajar por qué esto está ocurriendo. –

+0

Probablemente 'bool check = @" http://www.example.org/test?helloworld=foo¶bar "== uri.ToString();' es falso, ¿verdad? – t3hn00b

+0

Sí que es falso –

Respuesta

6

El cambio está relacionado con problemas con las versiones anteriores de .NET, que ahora han cambiado para ser más compatibles con los estándares. %B6 es UTF-16, pero de acuerdo con las normas UTF-8 se debe utilizar en el Uri, lo que significa que debe ser %C2%B6. Entonces, como %B6 no es UTF-8, ahora se ignora y no se decodifica correctamente.

Más detalles del connect report citado en forma literal a continuación.

.NET 4.5 se ha mejorado y la aplicación más compatible de la RFC 3987 que soporta reglas de análisis de IRI para el URI de. Los IRI son International Identificadores de recursos. Esto permite que los caracteres que no sean ASCII estén en una cadena de URI/IRI para ser analizados.

Antes de .NET 4.5, teníamos un manejo incoherente de los IRI. Tuvimos una entrada app.config su valor predeterminado es falso que se podría convertir en:

la que hizo un poco de manipulación de IRI/análisis. Sin embargo, tuvo algunos problemas. En particular, permitió un manejo incorrecto de la codificación porcentual. Los elementos codificados porcentuales en una cadena URI/IRI se supone que son octetos UTF-8 codificados por ciento según RFC 3987. No son interpretados como UTF-16 con porcentaje de codificación. Por lo tanto, el manejo de "% B6" es incorrecto de acuerdo con UTF-8 y no se producirá ninguna decodificación. La codificación UTF-8 correcta para ¶ es en realidad "% C2% B6".

Si la cadena fue esta vez:

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

entonces será conseguir normalizada en el método ToString() y el código porciento decodificado y se retira.

¿Puede proporcionar más información sobre las necesidades de su aplicación y el uso de del método ToString()? Por lo general, recomendamos la propiedad AbsoluteUri del objeto Uri para la mayoría de las necesidades de normalización.

Si este problema está bloqueando el desarrollo de aplicaciones y de negocios necesidades, por favor, avísenos a través de la "netfx45compat en Microsoft punto com" dirección de correo electrónico.

Thx,

equipo de redes

0

En esa situación no puedes hacer eso. El problema principal es el carácter "¶".

En .Net tenemos un problema con el carácter ¶. Puede hacer una investigación sobre eso.

Tome los parámetros uri 'uno por uno. Agréguelos por uno y compárelos. Puede ser que pueda usar un método para el carácter "¶" para crearlo o reemplazarlo.

Por ejemplo;

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) 

que va a trabajar

uri.AbsolutePath:/test

url.Anfitrión: http://www.example.org

uri.Query: holamundo = foo¶bar

+0

Funcionó antes de instalar VS2012 y debería funcionar de acuerdo con la documentación de MSDN. No me interesa el trabajo, es simple, me interesa saber por qué ya no funciona. –

8

Hay algunos cambios introducidos en .NET Framework 4.5, que se instala junto con VS2012, y que también es (a lo mejor de mi conocimiento) una llamada "actualización en el lugar". Esto significa que realmente actualiza .NET Framework 4.

Además, hay breaking changes documented in System.Uri. Uno de ellos dice El formulario de normalización Unicode C (NFC) ya no se realizará en las partes que no son de host de los URI. No estoy seguro de si esto es aplicable a su caso, pero podría servir como un buen punto de partida en su investigación del error.

+0

Interesante, explica por qué cambió - podría ser un efecto secundario de uno de esos cambios de última hora, esperaba haber obtenido una respuesta a través de la conexión pero no tuve suerte. –

+0

Buen lugar, sin embargo, indica que "Esto solo afecta a las aplicaciones que se dirigen a .NET Framework 4.5". – Justin

Cuestiones relacionadas