Обработка исключений при работе с Telegram API с помощью C#

Есть код для бота Telegram. Суть задачи заключается в том, что нужно во время получения конкретного типа сообщения (фото или видео), выполнять определённый метод.

        static string chatID = "***";
    static string securePART = ":***";
    int update_id = 0;

    TelegramBotClient botClient = new TelegramBotClient(chatID + securePART);

    string primaryUrl = @"https://api.telegram.org/bot*****/";

    WebClient webClient = new WebClient();
    public void GetMessagesUpdate()
    {
        var telegramBot = new TelegramBotClient(chatID + securePART);
        string url = $"{primaryUrl}getUpdates?offset={update_id}";
        var messageUpdate = webClient.DownloadString(url);


        var msgs = JObject.Parse(messageUpdate)["result"].ToArray();

        WriteLine(messageUpdate.ToString());
        foreach (dynamic item in msgs)
        {
            update_id = Convert.ToInt32(item.update_id) + 1;

            string userMessage = item.message.text;
            string userId = item.message.from.id;
            string useFirstrName = item.message.from.first_name;
            string UserLastName = item.message.from.last_name;

            string text = $"{useFirstrName} {UserLastName} {userId} {userMessage}";

            Console.WriteLine(text);

            switch (item.MessageType.Type)
            {
                case MessageType.Photo:
                    {
                        WriteLine("Прислали фото");
                    }
                    break;
                default:
                    {
                        WriteLine("Что-то пошло не так");
                    }
                    break;
            }
        }
    }

Во время выполнения оператора Switch вызывается исключение:

Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: Не удается выполнить привязки исполняющей среды по нулевой ссылке

Если коротко, я совершенно не понимаю, в чём заключается проблема? MessageType это перечисление.


Ответы (2 шт):

Автор решения: Peter Lavreniuk

Есть интересная книга - C# для профессионалов, от вот этого гражданина - Jon Skeet . Там подробно рассказывается о dynamic.

Как можно воспроизвести пример :

    dynamic test = new ExpandoObject();
    test.Property = 1;
    test.StrProperty = "123";

    Console.WriteLine(test.Property);
    Console.WriteLine(test.StrProperty);
    Console.WriteLine(test.UndefinedProperty);

На моменте Console.WriteLine(test.UndefinedProperty) у нас случается ошибка RuntimeBinderException. Потому что в среде выполнения не смогла произойти привязка, можно читать проще - у данного объекта нет такого свойства.

Как решить проблему?!

Ну можно тупо в лоб ловить исключение и его игнорировать:

        try
        {
            Console.WriteLine(test.UndefinedProperty);
        }
        catch (RuntimeBinderException)
        {
            //ignore
        }

А можно сделать статические метод (метод расширения не подойдет!):

    public static bool HasProperty(ExpandoObject obj, string name)
    {
        return ((IDictionary<string, object>)obj).ContainsKey(name);
    }

И использовать так :

        if (HasProperty(test, "UndefinedProperty"))
            Console.WriteLine(test.UndefinedProperty);
        else
            Console.WriteLine("Sad!");

Полезные ссылки :

Использование типа dynamic

C# in Depth, Fourth Edition

→ Ссылка
Автор решения: Денис

Решение:

В моём случае, я решил возникающее исключение следующим образом: Я узнал, что у библиотеки Telegram.Bot существует событие event EventHandler<MessageEventArgs> OnMessage; (ссылка)

Я переписал код, который отвечает за вывод сообщений используя событие. Вкратце, это выглядит так:

     public void MainMethod()
    {
        botClient.OnMessage += GetMessagesUpdate;
        botClient.StartReceiving();
    }

     private void GetMessagesUpdate(object sender, Telegram.Bot.Args.MessageEventArgs e)
    {
        var telegramBot = new TelegramBotClient(chatID + securePART);
        string url = $"{primaryUrl}getUpdates?offset={update_id}";
        var messageUpdate = webClient.DownloadString(url);


        // Парсим JSON
        foreach (dynamic item in msgs)
        {
           if (e.Message.Type == Telegram.Bot.Types.Enums.MessageType.Document)
            {
                // Делаем определённые действия
            }
        }
    }

В таком варианте возможно указывать действия для определённого типа переданных боту типов документов.

@Peter-Lavreniuk, благодарю за ссылки.

→ Ссылка