2011-08-11 30 views
8

En primer lugar, algunos antecedentes rápidos ... Como parte de una integración con un proveedor externo, tengo una aplicación web C# .Net que recibe una URL con un montón de información en el cadena de consulta. Esa URL está firmada con un hash MD5 y una clave secreta compartida. Básicamente, selecciono la cadena de consulta, elimino su hash, realizo mi propio hash en la cadena de consulta restante y me aseguro de que el mío coincida con el que se proporcionó..Net Uri Encoding RFC 2396 vs RFC 3986

estoy recuperando el URI de la siguiente manera ...

Uri uriFromVendor = new Uri(Request.Url.ToString()); 
string queryFromVendor = uriFromVendor.Query.Substring(1); //Substring to remove question mark 

Mi problema se derivan de las cadenas de consulta que contienen caracteres especiales como diéresis (ü). El vendedor está calculando su hash basado en la representación RFC 2396 que es %FC. Mi aplicación C# .Net está calculando que es hash basado en la representación RFC 3986 que es %C3%BC. No hace falta decir que nuestros hash no coinciden y arrojo mis errores.

Extrañamente, el documentation for the Uri class in .Net dice que debe seguir RFC 2396 a menos que se establezca de otra manera en RFC 3986, pero no tengo la entrada en mi archivo web.config que dicen es necesaria para este comportamiento.

¿Cómo puedo forzar al constructor de Uri a usar la convención RFC 2396?

En su defecto, ¿hay una manera fácil de convertir los pares de octetos RFC 3986 en octetos RFC 2396?

+1

Nada que ver con su pregunta, pero ¿por qué está creando un nuevo Uri aquí? Simplemente puede hacer 'string queryFromVendor = Request.Url.Query.Substring (1);' – magnattic

+0

¿Qué versión de .NET está usando? –

+0

Estoy usando .Net 4.0. Además, curiosamente, cuando traté de usar 'Request.Url.Query', la diéresis venía como'% ufffd', que es el carácter.. – Colin

Respuesta

2

nada que ver con su pregunta, pero ¿por qué estás creando un nuevo Uri aquí? Solo puede hacer string queryFromVendor = Request.Url.Query.Substring(1); - atticae

+1 por atticae! Volví para tratar de eliminar el Uri extraño que estaba creando y, de repente, la cuerda tenía la diéresis codificada como UTF-8 en lugar de UTF-16.

Al principio, no pensé que esto funcionaría. En algún lugar a lo largo de la línea, intenté recuperar la URL usando Request.QueryString, pero esto estaba causando que la diéresis apareciera como %ufffd, que es el carácter . Con el interés de tomar una nueva perspectiva, probé la sugerencia de Atticae y funcionó.

Estoy bastante seguro de que la respuesta tiene que ver con something I read here.

C# utiliza UTF-16 en todas sus cuerdas, con herramientas para codificar cuando se trata de lidiar con las corrientes y los archivos que nos llevan a ...

ASP.NET utiliza UTF-8 por omisión, y es difícil pensar en un momento en que no es una buena opción ...

Mis problemas provenían de aquí ...

Uri uriFromVendor = new Uri(Request.Url.ToString()); 

al tomar el URI y Request.Url creando otro uri, estaba codificando como el estándar C# UTF-16. Al usar el uri original, permaneció en el estándar .Net UTF-8.

Gracias a todos por su ayuda.

+0

Me alegro de poder ayudar. – magnattic

1

Me pregunto si esto es un poco de una pista falsa:

Digo esto porque es la representación FC UTF16 de la u con diéresis; C2BC es la representación UTF8.

Me pregunto si uno de los métodos System.Text.Encoding para convertir los datos de origen en una cadena .Net normal podría ayudar.

Esta pregunta podría ser de interés también: Encode and Decode rfc2396 URLs

1

No sé acerca de la codificación estándar para los constructores Uri, pero si todo lo demás falla siempre se puede decodificar la dirección usted mismo y codificarlo en cualquier codificación te gusta .

El HttpUtility-Class tiene un método UrlDecode() y UrlEncode(), que le permite especificar el System.Text.Encoding como segundo parámetro.

Por ejemplo:

string decodedQueryString = HttpUtility.UrlDecode(Request.Url.Query.Substring(1)); 
string encodedQueryString = HttpUtility.UrlEncode(decodedQueryString, System.Text.Encoding.GetEncoding("utf-16")); 
// calc hash here 
+0

Parece que el método UrlEncode se vuelve demasiado entusiasta. la salida ha codificado todo en la cadena ... c% 00o% 00n% 00f% 00i% 00r% 00m% 00a% 00t% 00i% 00o% 00 ... – Colin

+0

Nota: Se las arregló para convertir la diéresis de nuevo en '% FC' embargo. ¿Hay alguna manera de ser un poco más selectivo para que no codifique los signos y, y los% 00? – Colin

+0

Ok, antes que nada: el resultado% 00 es el resultado de la codificación utf-16, que acabo de usar como ejemplo aquí. Reemplácelo con la codificación que desee. Si desea ü convertirse en% FC, tal vez esté buscando latin1: 'System.Text.Encoding.GetEncoding (" latin1 ")' – magnattic

Cuestiones relacionadas