Eu tenho um aplicativo que envia uma solicitação POST ao software do fórum VB e efetua login em alguém (sem definir cookies ou qualquer coisa).
Depois que o usuário está logado, crio uma variável que cria um caminho em sua máquina local.
c: \ tempfolder \ date \ nome de usuário
O problema é que alguns nomes de usuário estão lançando a exceção "Caracteres ilegais". Por exemplo, se meu nome de usuário fosse mas|fenix
, isso lançaria uma exceção ..
Path.Combine( _
Environment.GetFolderPath(System.Environment.SpecialFolder.CommonApplicationData), _
DateTime.Now.ToString("ddMMyyhhmm") + "-" + form1.username)
Não quero removê-lo da string, mas uma pasta com seu nome de usuário é criada por FTP em um servidor. E isso leva à minha segunda pergunta. Se estou criando uma pasta no servidor, posso deixar os "caracteres ilegais" em? Só pergunto isso porque o servidor é baseado no Linux e não tenho certeza se o Linux aceita ou não.
EDIT: Parece que a codificação de URL NÃO é o que eu quero .. Aqui está o que eu quero fazer:
old username = mas|fenix
new username = mas%xxfenix
Onde% xx é o valor ASCII ou qualquer outro valor que identifique facilmente o caractere.
Respostas:
Editar: observe que esta resposta está desatualizada. Veja a resposta de Siarhei Kuchuk abaixo para uma solução melhor
UrlEncoding fará o que você está sugerindo aqui. Com o C #, você simplesmente usa
HttpUtility
, como mencionado.Você também pode regexar os caracteres ilegais e depois substituí-los, mas isso fica muito mais complexo, pois você terá que ter algum tipo de máquina de estado (alternar ... caso, por exemplo) para substituir pelos caracteres corretos. Como
UrlEncode
isso é feito com antecedência, é bastante fácil.Quanto ao Linux versus Windows, existem alguns caracteres aceitáveis no Linux que não estão no Windows, mas eu não me preocuparia com isso, pois o nome da pasta pode ser retornado decodificando a string Url, usando
UrlDecode
, para que você possa percorrer o alterar.fonte
A potentially dangerous Request.Path value was detected from the client
.Venho experimentando os vários métodos que o .NET fornece para codificação de URL. Talvez a tabela a seguir seja útil (como saída de um aplicativo de teste que escrevi):
As colunas representam codificações da seguinte maneira:
UrlEncoded:
HttpUtility.UrlEncode
UrlEncodedUnicode:
HttpUtility.UrlEncodeUnicode
UrlPathEncoded:
HttpUtility.UrlPathEncode
EscapedDataString:
Uri.EscapeDataString
EscapedUriString:
Uri.EscapeUriString
HtmlEncoded:
HttpUtility.HtmlEncode
HtmlAttributeEncoded:
HttpUtility.HtmlAttributeEncode
HexEscaped:
Uri.HexEscape
NOTAS:
HexEscape
pode lidar apenas com os primeiros 255 caracteres. Portanto, lança umaArgumentOutOfRange
exceção para os caracteres latinos A-Extended (por exemplo, Ā).Esta tabela foi gerada no .NET 4.0 (consulte o comentário de Levi Botelho abaixo que diz que a codificação no .NET 4.5 é um pouco diferente).
EDITAR:
Adicionei uma segunda tabela com as codificações do .NET 4.5. Veja esta resposta: https://stackoverflow.com/a/21771206/216440
EDIT 2:
Como as pessoas parecem gostar dessas tabelas, pensei que você poderia gostar do código-fonte que gera a tabela, para que você possa se divertir. É um aplicativo de console simples em C #, que pode atingir o .NET 4.0 ou 4.5:
fonte
Uri.EscapeUriString
, mas cuidado, ele não suporta umnull
argumento.UrlPathEncode
. Então, basicamente, substituaUrlPathEncode
porUri.EscapeUriString
.Você deve codificar apenas o nome de usuário ou outra parte do URL que possa ser inválida. URL que codifica um URL pode causar problemas, uma vez que algo como isto:
Produzirá
Obviamente, isso não vai funcionar bem. Em vez disso, você deve codificar SOMENTE o valor do par de chave / valor na cadeia de consulta, desta forma:
Espero que ajude. Além disso, como teedyay mencionado, você ainda precisa fazer personagens de nome de arquivo certeza ilegais são removidos ou então o sistema de arquivos não vai gostar do caminho.
fonte
?
(já que assume que a string de consulta já está codificada). No exemplo de Dan Herbert, parece que ele está fingindoExample
ser o texto que requer codificação, portantoHttpUtility.UrlPathEncode("http://www.google.com/search?q=Example");
não funcionará. Experimente com?q=Ex&ple
(onde está o resultado desejado?q=Ex%26ple
). Não funcionará porque (1) UrlPathEncode não toca em nada depois?
e (2) UrlPathEncode não codifica de&
qualquer maneira.&
, porque você precisa delimitar os parâmetros da string de consulta. Mas há momentos em que você também deseja e comercial codificado.Melhor maneira é usar
Uri.EscapeUriString
para não fazer referência ao perfil completo de .net 4.
fonte
Uri.EscapeDataString
NÃOUri.EscapeUriString
Leia este comentário, ele me ajudou.Desde o .NET Framework 4.5 e o .NET Standard 1.0, você deve usar
WebUtility.UrlEncode
. Vantagens sobre alternativas:Faz parte do .NET Framework 4.5+, .NET Core 1.0+, .NET Standard 1.0+, UWP 10.0+ e todas as plataformas Xamarin.
HttpUtility
, embora esteja disponível no .NET Framework anterior (.NET Framework 1.1+), fica disponível em outras plataformas muito mais tarde (.NET Core 2.0+, .NET Standard 2.0+) e ainda está indisponível no UWP (consulte a pergunta relacionada ).No .NET Framework, ele reside em
System.dll
, portanto, não requer nenhuma referência adicional, ao contrárioHttpUtility
.Diferentemente, ele escapa caracteres para URLs
Uri.EscapeUriString
(veja os comentários na resposta de drweb86 ).Ela não possui limites no comprimento da string , ao contrário
Uri.EscapeDataString
(consulte a pergunta relacionada ), portanto pode ser usada para solicitações POST, por exemplo.fonte
Levi Botelho comentou que a tabela de codificações geradas anteriormente não é mais precisa para o .NET 4.5, uma vez que as codificações mudaram ligeiramente entre o .NET 4.0 e o 4.5. Então, eu regenerei a tabela para o .NET 4.5:
As colunas representam codificações da seguinte maneira:
HttpUtility.UrlEncode
HttpUtility.UrlEncodeUnicode
HttpUtility.UrlPathEncode
WebUtility.UrlEncode
Uri.EscapeDataString
Uri.EscapeUriString
HttpUtility.HtmlEncode
HttpUtility.HtmlAttributeEncode
WebUtility.HtmlEncode
Uri.HexEscape
NOTAS:
O HexEscape pode manipular apenas os primeiros 255 caracteres. Portanto, lança uma exceção ArgumentOutOfRange para os caracteres latinos A-Extended (por exemplo, Ā).
Esta tabela foi gerada no .NET 4.5 (consulte a resposta https://stackoverflow.com/a/11236038/216440 para obter as codificações relevantes para o .NET 4.0 e abaixo).
EDITAR:
fonte
(Net4.0) ? %3f................................
(Net4.5) ? %3f ..................................
A codificação de URL é fácil no .NET. Usar:
Se isso for decodificado para obter o nome da pasta, você ainda precisará excluir caracteres que não podem ser usados nos nomes das pastas (*,?, /, Etc.)
fonte
Se você não conseguir ver o System.Web, altere as configurações do projeto. A estrutura de destino deve ser ".NET Framework 4" em vez de ".NET Framework 4 Client Profile"
fonte
A implementação do .NET
UrlEncode
não está em conformidade com a RFC 3986.Alguns caracteres não são codificados, mas deveriam ser. Os
!()*
caracteres estão listados na seção 2.2 da RFC como caracteres reservados que devem ser codificados, mas o .NET falha ao codificar esses caracteres.Alguns caracteres são codificados, mas não devem ser. Os
.-_
caracteres não estão listados na seção 2.2 da RFC como um caractere reservado que ainda não deve ser codificado. O .NET codifica erroneamente esses caracteres.O RFC especifica que, para serem consistentes, as implementações devem usar HEXDIG em maiúsculas, onde o .NET produz HEXDIG em minúsculas.
fonte
Acho que as pessoas aqui foram desviadas pela mensagem UrlEncode. URLEncoding não é o que você deseja - você deseja codificar coisas que não funcionarão como um nome de arquivo no sistema de destino.
Supondo que você queira alguma generalidade - fique à vontade para encontrar os caracteres ilegais em vários sistemas (MacOS, Windows, Linux e Unix), junte-os para formar um conjunto de caracteres para escapar.
Quanto à fuga, um HexEscape deve ficar bem (Substituindo os caracteres por% XX). Converta cada caractere em bytes UTF-8 e codifique tudo> 128 se desejar oferecer suporte a sistemas que não executam unicode. Porém, existem outras maneiras, como usar barras invertidas "\" ou codificação HTML "" ". Você pode criar o seu próprio. Tudo o que qualquer sistema precisa fazer é 'codificar' o caractere incompatível. Os sistemas acima permitem recriar o nome original - mas algo como substituir os caracteres incorretos por espaços também funciona.
Na mesma tangente acima, o único a ser usado é
- Ele codifica tudo o que é necessário para o OAuth, não codifica o que o OAuth proíbe codificar e codifica o espaço como% 20 e não + (também na especificação OATH) Consulte: RFC 3986. AFAIK, este é o última especificação de URI.
fonte
Eu escrevi um método C # que codifica url TODOS os símbolos:
fonte
Idealmente, eles iriam para uma classe chamada "FileNaming" ou talvez apenas renomear Encode para "FileNameEncode". Nota: eles não foram projetados para lidar com caminhos completos, apenas os nomes de pastas e / ou arquivos. Idealmente, você deve dividir ("/") seu caminho completo primeiro e depois verificar as peças. E, obviamente, em vez de uma união, você pode simplesmente adicionar o caractere "%" à lista de caracteres não permitidos no Windows, mas acho que é mais útil / legível / factual dessa maneira. Decode () é exatamente o mesmo, mas alterna o Substituir (Uri.HexEscape (s [0]), s) "escapou" com o caractere.
Obrigado @ simon-tewsi pela tabela muito útil acima!
fonte
Path.GetInvalidFileNameChars()
Além da resposta de Dan Herbert, você deve codificar apenas os valores em geral.
Split possui o parâmetro params Split ('&', '='); expressão primeiramente dividida por & then '=', para que elementos ímpares sejam todos os valores a serem codificados, mostrados abaixo.
fonte