sexta-feira, 16 de fevereiro de 2007

0

Download de arquivos com nomes acentuados em ASP.NET

Tivemos a necessidade, esses dias, de desenvolver uma página ASP.NET que se encarregaria de fazer o download de um documento que só estaria acessível via impersonate, uma vez que estaria armazenado em outro servidor HTTP, autenticando via NTLM.

Dentre as possibilidades, acabamos por utilizar o System.Net.WebClient, passando as credenciais default e obtendo o conteúdo do arquivo em questão. O código foi mais ou menos como o que segue:

WebClient webClient = new WebClient();
webClient.Credentials = CredentialCache.DefaultCredentials;
byte[] data = webClient.DownloadData(endereco);
O problema foi que o nome do arquivo remoto eventualmente poderia incluir caracteres acentuados. Após muita pesquisa, chegamos à conclusão que isso não é possível, pois os nomes de arquivos no cabeçalho Content-Disposition são codificados em ASCII.

Ai vim documentar isso aqui, antes de cair na gandaia do Carnaval. Resolvi fazer mais uns testes e criei o código abaixo:
void Page_Load(object sender, EventArgs e)
{
Response.AddHeader("Content-Disposition", "attachment; filename=\"áéíóúçãõüàèìòù.txt\"");
Response.Write(DateTime.Now.ToString());
Response.End();
}
Acabei descobrindo coisas interessantes:

  • Se o nome do arquivo tiver caracteres especiais, o FireFox mantém os acentos corretos. Assim, o código acima funciona sem problemas para o FF2, mas gera caracteres estranhos no IE6;
  • Se você precisa de caracteres ASCII codificados, por que não usar o Server.UrlEncode? Alterei a página de testes e vi que o documento veio agora com o nome correto no IE6. Como nada vem fácil, o nome do documento no FF2 veio com os %nn característicos;
  • Sendo o alvo do meu trabalho apenas os browsers IE6, o problema estaria resolvido. Mas, por que não fazer o trabalho direito? Acabei com o código abaixo:
void Page_Load(object sender, EventArgs e)
{
string arquivo = "áéíóúçãõüàèìòù.txt";
if(Request.Browser.Browser == "IE")
arquivo = Server.UrlEncode(arquivo);
Response.AddHeader("Content-Disposition", "attachment; filename=\"" + arquivo + "\"");
Response.Write(DateTime.Now.ToString());
Response.End();
}
E é isso. Até a próxima.