WebClient.DownloadString resulta em caracteres mutilados devido a problemas de codificação, mas o navegador está OK

86

O seguinte código:

var text = (new WebClient()).DownloadString("http://export.arxiv.org/api/query?search_query=au:Freidel_L*&start=0&max_results=20"));

resulta em uma variável textque contém, entre muitas outras coisas, a string

"$ κ $ -Espaço de Minkowski, campo escalar e a questão da invariância de Lorentz"

No entanto, quando visito esse URL no Firefox, recebo

$ κ $ -pace de Minkowski, campo escalar e a questão da invariância de Lorentz

o que é realmente correto. Eu também tentei

var data = (new WebClient()).DownloadData("http://export.arxiv.org/api/query?search_query=au:Freidel_L*&start=0&max_results=20");
var text = System.Text.UTF8Encoding.Default.GetString(data);

mas isso deu o mesmo problema.

Não tenho certeza de onde está a culpa aqui. O feed está mentindo sobre ser codificado em UTF8 e o navegador é inteligente o suficiente para descobrir isso, mas não WebClient? O feed está corretamente codificado em UTF8, mas WebClientestá falhando de alguma outra forma? O que posso fazer para atenuar isso?

Domenic
fonte
6
UTF8Encoding.Defaulté Encoding.Default, na verdade , que é a codificação ANSI baseada nas configurações de idioma do sistema operacional.
svick de

Respostas:

205

Não está mentindo. Você deve definir a codificação do webclient primeiro, antes de chamar DownloadString.

using(WebClient webClient = new WebClient())
{
webClient.Encoding = Encoding.UTF8;
string s = webClient.DownloadString("http://export.arxiv.org/api/query?search_query=au:Freidel_L*&start=0&max_results=20");
}

Quanto ao motivo de sua alternativa não estar funcionando, é porque o uso é incorreto. Deve ser:

System.Text.Encoding.UTF8.GetString()
LostInComputer
fonte
9
Excelente obrigado! Estranho que o WebClientnão use os cabeçalhos para detectar isso, mas funciona perfeitamente, e entre você e @svick, eu entendo por que a outra coisa que tentei estava falhando miseravelmente também.
Domenic de
1
Funciona UploadStringtambém
irfandar