0
using System.Net.Http;

Встречались ли вы с проблемой, что сайты указывают некорректное значение charset в ContentType заголовке ? Т.е. указывают cp1251, а не windows-1251 и при сериализации содержимого HTTP выдаёт исключение InvalidOperationException.

Я вышел из ситуации и при таком исключении в catch проверяю наличие кривого значения, меняю на нормальное и ещё раз пытаюсь сериализовать.

Но может быть как то иначе это можно делать ?

А не тупо:

string contentType = response.Content.Headers.ContentType.CharSet.ToString();
contentType = contentType.ToLower();

if (contentType.Contains("cp1251"))
{
   response.Content.Headers.ContentType.CharSet = "windows-1251";
}

UPD: Вот хороший пример, facebook.com тоже выдаёт исключение.

введите сюда описание изображения

Xzizz
  • 1,592
  • 1
    А зачем исправлять при исключении, фактически уже после обработки, если можно сразу проверять и не получать исключение? – Геннадий П Dec 08 '19 at 11:52
  • 1
    Я сталкивался как то с подобным, работая с одним "буржуйским" сайтом, который неверно писал кодировку, пришел к банальному - конвертировал прямиком полученные байты в нужную мне кодировку. Если что, подобная реализация есть в этом ответе. – EvgeniyZ Dec 08 '19 at 11:56
  • @ГеннадийП т.е. каждый проверять и те 99% нормальные, теряя процессорное время ? Или дурной тон в catch проверять ? Я падаван в этом деле, а вы мои магистры xD Было бы здорово, если бы разъяснили. – Xzizz Dec 08 '19 at 12:25
  • 1
    @Vipz Проверка и замена по маленькому словарю занимает крайне мизерное время по сравнению с повторной задачей (в данном случае сериализация плюс другие задачи) – Геннадий П Dec 08 '19 at 12:32
  • @EvgeniyZ понял вас, спасибо! Вот мне много таких попалось, даже вообще не дописанные значения. А такой вопрос на перёд, если я буду все извлекать в utf-8 - не будут ли на каких то иероглифы вылезать ? Допустим если windows-1251, а я его как utf-8 получу по вашему методу. – Xzizz Dec 08 '19 at 12:33
  • @ГеннадийП круто, понял что пытались мне донести, спасибо! – Xzizz Dec 08 '19 at 12:36
  • 2
    если я буду все извлекать в utf-8 - не будут ли на каких то иероглифы вылезать? - конечно будут. Вообще я бы на вашем месте нашел бы способ автоматически "детектить" кодировку полученных байтов, ну или делайте словарь, как вам уже дали ответ. Вот например нашел на EnSO ответ, который автоматически обнаруживает кодировку байтов и выдает преобразованный текст, вам достаточно заменить byte[] b = File.ReadAllBytes(filename); на параметр и заменить из моего ответа строки преобразования на это: _ = detectTextEncoding(bytes, out data);. – EvgeniyZ Dec 08 '19 at 13:08
  • @EvgeniyZ конечно будут - исчерпывающий ответ. Спасибо! Буду теперь разбираться и думать. Всё же словарь в моём случае будет проще, чем детект xD Наверно даже просто двумя if 1251 и 8 буду вылавливать. Потому что другие я пока кодировки из 200к ссылок не встречал – Xzizz Dec 08 '19 at 13:58

1 Answers1

3

Чтобы не плодить кучу if при проверке можете использовать словарь и поиск по словарю:

        Dictionary<string, string> charsetDict = new Dictionary<string, string>
        {
            { "cp1251", "windows-1251" },
            { "win1251", "windows-1251" },
            { "utf-8", "UTF-8" },
            { "utf8", "UTF-8" },
        };

        string charsetTest = "cp1251";
        Console.WriteLine(charsetDict.FirstOrDefault(t => t.Key == charsetTest).Value ?? charsetTest);