2009-08-17 18 views
5

Estoy implementando la reescritura de URL en ASP.net y mis URL me están causando un montón de problemas.ASP.Net URL Encoding

La URL se genera a partir de una base de datos de categorías de departamentos &. Quiero que los empleados puedan agregar elementos a la base de datos con los caracteres especiales que sean apropiados sin romper el sitio.

Estoy codificando los datos antes de construir las URL.

Hay varios problemas ...

  1. IIS descodifica la URL antes de que llegue .net por lo que es imposible analizar adecuadamente cualquier cosa con un "/" en ella.
  2. ASP.net se confunde por la toma de URL "~" inútil dentro de ciertas páginas
  3. que migraron desde el construido en el servidor de prueba a mi servidor local de IIS (máquina XP) y cualquier URL que contiene una codificada & (% 26) me da un error de "Solicitud incorrecta".
  4. UrlEncode deja algunos caracteres de ruptura intactos, como '.'

Tenía otras dos publicaciones relacionadas sobre este tema, en ese momento solo veía los pequeños problemas, no el gran problema de la corriente ascendente. He encontrado algunos trucos de registro para resolver el problema de "Solicitud incorrecta", pero voy a implementarlo en un entorno de alojamiento compartido que lo hace inútil. También sé que esto es una solución para algunos problemas de seguridad, así que no quiero pasar necesariamente por alto sin saber qué tipo de gusanos puedo abrir.

En lugar de tratar de forzar .net para que me pase la URL en bruto, o anular la configuración de IIS, me gustaría crear URL verdaderamente seguras en primer lugar.

Notaré que he probado AntiXss.URLEncode, HttpUtility.URLEncode, URI.EscapeDataString. Incluso he intentado cosas estúpidas como double URLEncodng. ¿Existe alguna utilidad que haga lo que necesito, o realmente necesito hacer mi propia inversión? Incluso estoy considerando hacer algo Hacky como reemplazar el% con una cadena inusual de caracteres. El resultado final debería ser al menos legible, que era el punto de utilizar la reescritura de URL en primer lugar.

Lo siento por la larga publicación: solo quería asegurarme de haber incluido todos los detalles necesarios. Parece que no puedo encontrar información relevante sobre esto, y parece que sería un problema común, así que tal vez me esté perdiendo algo importante. Gracias por su ayuda y paciencia con la larga explicación.


Editar para mayor claridad:

Cuando digo las direcciones URL se construyen a partir de una base de datos de lo que quiero decir es que la estructura de directorios se contstructed de los departamentos y categorías en mi base de datos.

Algunas direcciones URL de ejemplo -

Mitienda/Refrigeración/Bar + Fridge.aspx
Mitienda/Cocina + Equipment.aspx
Mitienda/Cocina/corte + Boards.asxpx

Los problemas vienen en cuando Utilizo un departamento como "Bebida & Bar" o "Pastelería/Decoración" para construir mi URL. A pesar de estar codificados primero, estos causan los problemas antes mencionados.

Mis controladores ya están implementados y funcionan bien, excepto por los problemas especiales de codificación de caracteres.

+0

En aras de la divulgación completa aquí son mi otra posts- relacionada http://stackoverflow.com/questions/1274669/ url-encoding-being-lost-before-processing-asp-net - Pregunta similar pero estaba tratando de obligar a .net a darme la URL original en lugar de corregir la codificación en el enlace original. http://stackoverflow.com/questions/1194900/asp-net-path-problems-caused-by-encoded-urls Tratando de solucionar el problema "~" antes de darme cuenta de que había problemas mayores. –

Respuesta

4

Debería considerar tener una mesa fuera de su tabla de categoría/departamento que tiene una URL única para cada categoría. Luego puede usar una rutina especial para generar las URL. Puede ser una función escalar SQL o una función CLR, pero una de las cosas que haría es normalizar la URL para la web. Puede convertir "Beverage & Bar" en "Beverage-And-Bar" y "Pastry/Decorating" en "Pastry-Decorating". Principalmente, la rutina necesita reemplazar todos los caracteres de URL HTTP no válidos por otra cosa. Un ejemplo es este:

public static class URL 
{ 
    static readonly Regex feet = new Regex(@"([0-9]\s?)'([^'])", RegexOptions.Compiled); 
    static readonly Regex inch1 = new Regex(@"([0-9]\s?)''", RegexOptions.Compiled); 
    static readonly Regex inch2 = new Regex(@"([0-9]\s?)""", RegexOptions.Compiled); 
    static readonly Regex num = new Regex(@"#([0-9]+)", RegexOptions.Compiled); 
    static readonly Regex dollar = new Regex(@"[$]([0-9]+)", RegexOptions.Compiled); 
    static readonly Regex percent = new Regex(@"([0-9]+)%", RegexOptions.Compiled); 
    static readonly Regex sep = new Regex(@"[\s_/\\+:.]", RegexOptions.Compiled); 
    static readonly Regex empty = new Regex(@"[^-A-Za-z0-9]", RegexOptions.Compiled); 
    static readonly Regex extra = new Regex(@"[-]+", RegexOptions.Compiled); 

    public static string PrepareURL(string str) 
    { 
     str = str.Trim().ToLower(); 
     str = str.Replace("&", "and"); 

     str = feet.Replace(str, "$1-ft-"); 
     str = inch1.Replace(str, "$1-in-"); 
     str = inch2.Replace(str, "$1-in-"); 
     str = num.Replace(str, "num-$1"); 

     str = dollar.Replace(str, "$1-dollar-"); 
     str = percent.Replace(str, "$1-percent-"); 

     str = sep.Replace(str, "-"); 

     str = empty.Replace(str, string.Empty); 
     str = extra.Replace(str, "-"); 

     str = str.Trim('-'); 
     return str; 
    } 
} 

Puede hacer que esto sea una función de mejora de SQL o ejecutar la generación de URL como un proceso separado. Luego, para implementar la asignación, debe asignar la URL completa directamente a una ID de categoría. Este enfoque es mejor a largo plazo por varias razones. En primer lugar, no siempre generas URL, lo haces una vez y permanecen estáticas, no tienes que preocuparte de que el procedimiento cambie y GoogleBot no puede encontrar las URL antiguas. Además, si se produce una colisión, es posible que observe un posible nombre de categoría duplicado, ya que una colisión solo sería diferente por caracteres especiales. Finalmente, siempre puede ver sus URL desde la base de datos, sin tener que ejecutar la función de mapeo.

+1

Eso es absolutamente perfecto. Muchas gracias, me ahorraste más tiempo de lo que quisiera admitir. –

1

Tengo una reescritura de URL que implemento en el archivo global.asax en la solicitud de inicio de autenticación ya que tengo algo de seguridad. Aquí es donde tomo la url en bruto y luego hago la búsqueda de db. esto luego reescribe la ruta a la página aspx y todos los parámetros se pasan a través de la cadena de consulta. No es necesario codificar.

Sin embargo, si está usando la url para cambiar realmente los datos, entonces puedo ver que tendrá grandes problemas ya que está utilizando efectivamente http GET para cambiar la base de datos. Por lo general, se lo considera una mala idea, y no algo que hago.

Solo uso una solicitud posterior para hacer cualquier manipulación de databse. Esto mantiene la URL limpia ya que todos los datos están en el formulario de página.

El único problema que tuve fue establecer la URL correcta en la página.form.action que en la mayoría de los casos es la url en bruto.

Si son los nombres de categoría que están causando el problema, entonces quizás deba restringir los nombres a caracteres alfanuméricos solamente y cambiar espacios por "-". IIS lanzará un wobbly con puntos "." como busca los nombres de los archivos.

P.S. IIS no entiende la tilde "~", esto es algo que el compilador entiende. por lo tanto, si lo usa en una etiqueta de anclaje, no funcionará como se esperaba y debería usar la raíz de la aplicación en lugar de la tilde.

Editar:

OK, parece que un problema con IIS tener problemas con ciertos personajes como./y &. Incluso si usa urlencode, IIS intentará implementar sus propios significados. Como tal, estiman que la eliminación de ellos de modo:

Bebidas & bar se convierte en BeverageBar

pastelería/decoración se convierte en PastryDecorating.

Esto mantendrá las URL limpias, pero significa una columna adicional en la base de datos para que pueda restar importancia a la url contra este nombre de categoría abreviado.

+0

Lo siento, debería haber sido más claro: no estoy haciendo ninguna manipulación de la base de datos con mis URL. Mi tienda está dividida en departamentos y categorías. En lugar de estar codificado, la estructura del directorio se construye a partir de la base de datos. Los diversos menús tienen enlaces de la forma Mystore/Department o Mystore/Department/Category que, aunque IIS está codificado y es técnicamente correcto, antes de que la solicitud llegue a mi httpHandler. –

+0

Esa podría ser la mejor solución. Puede que solo haya estado complicando demasiado las cosas. Mi única preocupación es que voy a necesitar poder buscar elementos de la URL que podrían complicarse por un método de codificación no reversible. Mi única otra idea era usar Uri.EscapeDataString (b) .Replace ("%", "_") que estoy bastante seguro de que me condenarían al infierno de los programadores. Muchas gracias por sus respuestas rápidas y ayuda en esto ... Voy a echar un vistazo a mi código para ver si esto funciona. –

+0

Muchas gracias por su ayuda. Este es uno de esos momentos en los que estoy profundamente frustrado porque no puedo aceptar respuestas múltiples. Me apuntaste en la dirección correcta y me pusiste de nuevo en camino con esto ... ¡Gracias! –

1

Estoy teniendo exactamente el mismo problema. Gracias por escribirlo tan bien. En realidad, me ayudó a entender mejor el problema.

Sin embargo, tuve algunas otras consideraciones. Uno de los objetivos que tengo es apoyar la posibilidad de que cualquier personaje esté en la URL, que se basa en el título de un artículo. Además, quiero asegurar la singularidad en la codificación y un proceso de codificación/decodificación bidireccional.

Así que hice algunas codificaciones manuales para resolver el problema. Esto no eliminará por completo la codificación porcentual, pero la reducirá en gran medida y evitará que los usuarios generen una URL inaccesible. Mi proceso comienza con el uso de la función Server.URLEncode. Pero esto no elimina los problemas en la url. Como IIS está decodificando la url y luego pasándola a la aplicación, ciertos caracteres la romperán con una excepción de solicitud peligrosa. Estos caracteres incluyen +, &, /, !, *, ., ( y ). Entonces, en esos personajes más otros personajes que me gustaría hacer más legibles hago una doble codificación para una url más útil. La codificación también es difícil debido a la cantidad limitada de caracteres permitidos en una url. Antes de codificar, convertí todas las letras en mayúsculas y luego hice la codificación con minúsculas. Esto evita que sea totalmente decodificable, pero puedo hacer una coincidencia en la base de datos o en el código haciendo que el valor que deseo corresponder sea en mayúsculas.

Bueno, aquí está mi código. La retroalimentación sería apreciada. Oh ya, esto está en VB, pero las cosas deberían transferirse a C# lo suficientemente fácil.

Dim strReturn As String = Trim(strStringToEncode) 
strReturn = Server.UrlEncode(strReturn) 

strReturn = strReturn.Replace("-", "dash").Replace("+", "-") 

strReturn = strReturn.Replace("%26", "and"). 
        Replace("%2f", "or"). 
        Replace("!", "excl"). 
        Replace("*", "star"). 
        Replace("%27", "apos"). 
        Replace("(", "lprn"). 
        Replace(")", "rprn"). 
        Replace("%3b", "semi"). 
        Replace("%3a", "coln"). 
        Replace("%40", "at"). 
        Replace("%3d", "eq"). 
        Replace("%2b", "plus"). 
        Replace("%24", "dols"). 
        Replace("%25", "pct"). 
        Replace("%2c", "coma"). 
        Replace("%3f", "query"). 
        Replace("%23", "hash"). 
        Replace("%5b", "lbrk"). 
        Replace("%5d", "rbrk"). 
        Replace(".", "dot"). 
        Replace("%3e", "gt"). 
        Replace("%3c", "lt") 

Return strReturn 
+0

Ya encontré un problema. La exploración de URL rechaza la cita inteligente simple. – Nate

+0

Se encontraron muchas citas que hacen enojar a urlscan. Esto ayudará a arreglarlo. Reemplazar ("% e2% 80% 99", "rsquo"). Reemplazar ("% e2% 80% 98", "lsquo"). Reemplazar ("% e2% 80% 9d", "rdquo"). Reemplazar ("% e2% 80% 9c", "ldquo"). Reemplazar ("% e2% 80% 9b", "lsrquo"). Reemplazar ("% e2% 80% 9f", "ldrquo"). – Nate

+0

Eche un vistazo a los parámetros de web.config como 'requestFiltering allowDoubleEscaping =" true "' (http://stackoverflow.com/a/1453287/1178314) y 'httpRuntime requestValidationMode =" 2.0 "relaxedUrlToFileSystemMapping =" true "requestPathInvalidCharacters =" " '. En mi caso de uso, me permite admitir muchos más caracteres en las URL. –

0

supongo que busca HttpUtility.UrlEncode y HttpUtility.HtmlDecode

string url = "http://www.google.com/search?q=" + HttpUtility.UrlEncode("Example"); 
+1

Gracias por la información, aunque el problema era más que urlencode/decode no funcionaba, ya que asp.net o iis aún rechazaban las URL codificadas. Creo que terminé usando un esquema de sustitución en su lugar, pero esto fue un tiempo, así que estoy un poco confuso. –