Barra codificada por URL no URL

Meu mapa é:

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

Se eu usar o URL http://localhost:5000/Home/About/100%2f200 não há rota correspondente. Eu mudo o URL para http://localhost:5000/Home/About/100 seguida, a rota é correspondida novamente.

Existe alguma maneira fácil de trabalhar com parâmetros que contenham barras? Outros valores de escape (espaço %20 ) parecem funcionar.

EDITAR:

Codificar Base64 funciona para mim. Isso torna o URL feio, mas tudo bem por enquanto.

 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:

No final, descobriu-se que a melhor maneira era salvar uma string bem formatada para cada item que eu precisava selecionar. Isso é muito melhor porque agora eu só codifico valores e nunca os decodifico. Todos os caracteres especiais se tornam “-“. Muitas das minhas tabelas de database agora têm essa coluna adicional “URL”. Os dados são bastante estáveis, é por isso que eu posso seguir esse caminho. Posso até verificar, se os dados em “URL” são únicos.

EDIT2:

Também atente para o caráter de espaço. Parece ok no VS integrado servidor web, mas é diferente no iis7 corretamente url codificar espaço caractere

Se é apenas seu último parâmetro, você poderia fazer:

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

No .NET 4.0 beta 2, a equipe do CLR ofereceu uma solução alternativa.

Adicione isto ao seu arquivo web.config:

      

Isso faz com que a class Uri se comporte de acordo com o RFC que descreve os URIs, permitindo que as barras sejam escapadas no caminho sem serem removidas do escape. A equipe do CLR informa que eles se desviam da especificação por motivos de segurança, e configurar isso no arquivo .config basicamente faz com que você tome posse das considerações adicionais de segurança envolvidas em não remover as barras cortadas.

Aqui está uma explicação simples da solução e um resumo do que já foi dito.

Solicitação:

  1. UrlEncode seu caminho.
  2. Substitua o ‘%’ por ‘!’.
  3. Faça o pedido.

Lado da resposta:

  1. Substitua o ‘!’ com ‘%’.
  2. UrlDecode seu caminho.
  3. Use os parâmetros como eles foram planejados.

Enxague, repita, aproveite.

Uma outra opção é usar um valor de querystring. Muito coxo, mas mais simples que a codificação personalizada.

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

O mesmo para o Java / Tomcat.

Ainda há um problema se você tiver um “/” (% 2F) codificado em seu URL.

RFC 3986 – Seção 2.2 diz: “Se os dados para um componente URI entrassem em conflito com o propósito de um caracter reservado como um delimitador, então os dados conflitantes devem ser codificados em porcentagem antes que o URI seja formado.” (RFC 3986 – Seção 2.2)

Mas há um problema com o Tomcat:

http://tomcat.apache.org/security-6.html – Corrigido no Apache Tomcat 6.0.10

importante: Directory traversal CVE-2007-0450

Tomcat permite ‘\’, ‘% 2F’ e ‘% 5C’ […].

As seguintes propriedades do sistema Java foram adicionadas ao Tomcat para fornecer controle adicional da manipulação de delimitadores de caminho em URLs (ambas as opções padrão para false):

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

Devido à impossibilidade de garantir que todas as URLs sejam tratadas pelo Tomcat como elas estão em servidores proxy, o Tomcat sempre deve ser protegido como se nenhum access de contexto restritor de proxy tivesse sido usado.

Afeta: 6.0.0-6.0.9

Portanto, se você tiver uma URL com o caractere% 2F, o Tomcat retornará: “400 URI inválido: noSlash”

Você pode alternar do bugfix no script de boot do Tomcat:

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

Você pode evitar as sugestões de codificação / decodificação dupla acima e simplesmente usar HttpServerUtility.UrlTokenEncode e o UrlTokenDecode correspondente.

Isso é interessante sobre o .NET 4. De qualquer forma, este link descreve o RFC 1738 e inclui quais caracteres precisam de codificação e quais são apenas “inseguros”. Texto do link

Se eu quiser uma URL amigável para SEO, (como quando você quer colocar um assunto na URL do fórum), pule a codificação e substitua qualquer coisa que não seja 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); } 

Como sugerido aqui, quando o problema foi enfrentado pelos desenvolvedores do Symfony 1.x (+ sugerido nos comentários do PHP para urlencode() ):

  • Codificar ‘/’ para ‘% 2F’ antes de urlencode()
  • Decodifique ‘% 2F’ para ‘/’ depois (se necessário) urldecode()

Nota: você pode usar rawurlencode() , mas você ainda terá que urlencode ‘/’ duas vezes.

Vantagens:

  • Evita a necessidade de processos de escape adicionais (se replace ‘/’ por um caractere especial como ‘!’ Ou ‘_’)
  • Não depende de nenhuma configuração do servidor, como AllowEncodedSlashes for Apache

Apenas use Server.UrlDecode . Vai funcionar, eu testei.