c# asp.net-mvc asp.net-mvc-routing urlencode

c# - Barra URL codificada en URL



asp.net-mvc asp.net-mvc-routing (9)

Mi mapa es:

routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with params new { controller = "Home", action = "Index", id = "" } // Param defaults );

Si uso la URL http://localhost:5000/Home/About/100%2f200 no hay una ruta que coincida. Cambio la URL a http://localhost:5000/Home/About/100 y la ruta vuelve a coincidir.

¿Hay alguna manera fácil de trabajar con parámetros que contienen barras diagonales? Otros valores escapados (espacio %20 ) parecen funcionar.

EDITAR:

Para codificar Base64 funciona para mí. Hace que la URL sea fea, pero está bien por ahora.

public class UrlEncoder { public string URLDecode(string decode) { if (decode == null) return null; if (decode.StartsWith("=")) { return FromBase64(decode.TrimStart(''='')); } else { return HttpUtility.UrlDecode( decode) ; } } public string UrlEncode(string encode) { if (encode == null) return null; string encoded = HttpUtility.PathEncode(encode); if (encoded.Replace("%20", "") == encode.Replace(" ", "")) { return encoded; } else { return "=" + ToBase64(encode); } } public string ToBase64(string encode) { Byte[] btByteArray = null; UTF8Encoding encoding = new UTF8Encoding(); btByteArray = encoding.GetBytes(encode); string sResult = System.Convert.ToBase64String(btByteArray, 0, btByteArray.Length); sResult = sResult.Replace("+", "-").Replace("/", "_"); return sResult; } public string FromBase64(string decode) { decode = decode.Replace("-", "+").Replace("_", "/"); UTF8Encoding encoding = new UTF8Encoding(); return encoding.GetString(Convert.FromBase64String(decode)); } }

EDIT1:

Al final resultó que la mejor manera era guardar una cadena muy bien formateada para cada elemento que debía seleccionar. Eso es mucho mejor porque ahora solo codigo valores y nunca los decodifico. Todos los caracteres especiales se convierten en "-". Muchas de mis tablas db ahora tienen esta columna adicional "URL". La información es bastante estable, por eso puedo ir por este camino. Incluso puedo verificar si los datos en "URL" son únicos.

EDIT2:

También ten cuidado con el carácter espacial. Se ve bien en el servidor web integrado VS pero es diferente en iis7. Carácter de espacio de codificación local de URL.


Aquí hay una explicación simple de la solución y una suma de lo que ya se ha dicho.

Lado de solicitud:

  1. UrlEncadena tu camino.
  2. Reemplace el ''%'' con ''!''.
  3. Haga la solicitud

Lado de respuesta:

  1. Reemplace la ''!'' con ''%''.
  2. UrlDecode tu camino.
  3. Use los parámetros como fueron diseñados.

Enjuague, repita, disfrute.


Como se sugiere here cuando los desarrolladores de Symfony 1.x se enfrentaron al problema (+ se sugirió en los comentarios de PHP para urlencode() ):

  • Codifique ''/'' a ''% 2F'' antes de urlencode()
  • Decodifique ''% 2F'' en ''/'' después de (si es necesario) urldecode()

Nota: puede usar rawurlencode() , pero igual tendrá que urlencode ''/'' dos veces.

Ventajas:

  • Evita la necesidad de procesos de escape adicionales (si reemplaza ''/'' con un carácter especial como ''!'' O ''_'')
  • No confía en ninguna configuración de servidor, como AllowEncodedSlashes para Apache

En .NET 4.0 beta 2, el equipo de CLR ofreció una solución alternativa.

Agregue esto a su archivo web.config:

<uri> <schemeSettings> <add name="http" genericUriParserOptions="DontUnescapePathDotsAndSlashes" /> </schemeSettings> </uri>

Esto hace que la clase Uri se comporte de acuerdo con el RFC que describe los URI, lo que permite que las barras sean escapadas en el camino sin ser guardadas. El equipo de CLR informa que se desvía de la especificación por razones de seguridad, y establecer esto en su archivo .config básicamente le hace tomar posesión de las consideraciones de seguridad adicionales involucradas en no desamarrar las barras inclinadas.


Eso es interesante sobre .NET 4. De todos modos, este enlace describe RFC 1738 e incluye qué caracteres necesitan codificación y cuáles son simplemente "inseguros". Texto del enlace

Si quiero una URL amigable con SEO, (como cuando desea colocar un tema de publicación en el foro en la URL), es omitir la codificación y reemplazar todo lo que no sea AZ, az, 0-9.

public static string CreateSubjectSEO(string str) { int ci; char[] arr = str.ToCharArray(); for (int i = 0; i < arr.Length; i++) { ci = Convert.ToInt32(arr[i]); if (!((ci > 47 && ci < 58) || (ci > 64 && ci < 91) || (ci > 96 && ci < 123))) { arr[i] = ''-''; } } return new string(arr); }


Lo mismo para Java / Tomcat.

Todavía hay un problema si tiene un "/" codificado (% 2F) en su URL.

RFC 3986: la sección 2.2 dice: "Si los datos de un componente de URI entrarían en conflicto con el propósito de un carácter reservado como delimitador, entonces los datos en conflicto deben estar codificados porcentualmente antes de que se forme el URI". (RFC 3986 - Sección 2.2)

Pero hay un problema con Tomcat:

http://tomcat.apache.org/security-6.html - Solucionado en Apache Tomcat 6.0.10

importante: recorrido del directorio CVE-2007-0450

Tomcat permite ''/', ''% 2F'' y ''% 5C'' [...].

Las siguientes propiedades del sistema Java se han agregado a Tomcat para proporcionar un control adicional del manejo de los delimitadores de ruta en las URL (ambas opciones predeterminadas son falsas):

  • org.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH: true | false
  • org.apache.catalina.connector.CoyoteAdapter.ALLOW_BACKSLASH: true | false

Debido a la imposibilidad de garantizar que Tomcat maneje todas las URL como lo hacen en los servidores proxy, Tomcat siempre debe protegerse como si no se utilizara ningún acceso restringido al contexto.

Afecta: 6.0.0-6.0.9

Entonces, si tiene una URL con el carácter% 2F, Tomcat devuelve: "400 URI no válido: noSlash"

Puede cambiar la corrección de errores en el script de inicio de Tomcat:

set JAVA_OPTS=%JAVA_OPTS% %LOGGING_CONFIG% -Dorg.apache.tomcat.util.buf.UDecoder.ALLOW_ENCODED_SLASH=true


Otra opción es usar un valor de cadena de consulta. Muy cojo, pero más simple que la codificación personalizada.

http://localhost:5000/Home/About?100%2f200


Puede evitar las sugerencias de codificación doble / decodificación anteriores y simplemente usar HttpServerUtility.UrlTokenEncode y el correspondiente UrlTokenDecode.


Si es solo su último parámetro, podría hacer:

routes.MapRoute( "Default", // Route name "{controller}/{action}/{*id}", // URL with parameters new { controller = "Home", action = "Index", id = "" }); // Parameter defaults


Solo use Server.UrlDecode . Funcionará, lo he probado.