Обработка исключений при работе с 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 шт):
Есть интересная книга - 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!");
Полезные ссылки :
Решение:
В моём случае, я решил возникающее исключение следующим образом:
Я узнал, что у библиотеки 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, благодарю за ссылки.