Search code examples
c#asp.net-coreasp.net-web-apijson.netjson-deserialization

Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value - ASP.NET


How to properly deserialize POST method "Update" while developing Telegram bot in ASP.NET Core Web API by using Telegram.Bot package? I used DeserializeObject(string) method to do so, but it keeps returning the error: Newtonsoft.Json.JsonReaderException: Unexpected character encountered while parsing value

Code:

using Microsoft.AspNetCore.Mvc;
using Telegram.Bot;
using Telegram.Bot.Types;
using Telegram.Bot.Types.Enums;
using Telegram.Bot.Types.ReplyMarkups;
using Newtonsoft.Json;

namespace OfficeBooking.TelegramApi.Controllers
{
    [ApiController]
    [Route(template: "api/message")]
    public class TelegramBotController : ControllerBase
    {
        private readonly TelegramBotClient _telegramBotClient;

        public TelegramBotController(TelegramBot telegramBot)
        {
            _telegramBotClient = telegramBot.GetBot().Result;
        }

        [HttpPost]
        public async Task <IActionResult> Update([FromBody]object update)
        {
            var upd = JsonConvert.DeserializeObject<Update>(update.ToString());
            var chat = upd.Message?.Chat;

            if (chat == null)
            {
                return Ok();
            }

            await _telegramBotClient.SendTextMessageAsync(
                    chatId: chat.Id,
                    text: "Testing sendMessage method",
                    parseMode: ParseMode.MarkdownV2,
                    disableNotification: false,
                    replyMarkup: new InlineKeyboardMarkup(
                        InlineKeyboardButton.WithUrl(
                            "Check sendMessage method",
                            "https://core.telegram.org/bots/api#sendmessage")));

            return Ok();
        }
    }
}

Solution

  • I think you should try to lean on ASP.NET Core to parse your json input. You can simply specify type Update instead of object and it will do the rest for you. You just need to use ready object with type Update:

            [HttpPost]
            public async Task <IActionResult> Update([FromBody]Update update)
            {
                var chat = update.Message?.Chat;
    
                if (chat == null)
                {
                    return Ok();
                }
    
                await _telegramBotClient.SendTextMessageAsync(
                        chatId: chat.Id,
                        text: "Testing sendMessage method",
                        parseMode: ParseMode.MarkdownV2,
                        disableNotification: false,
                        replyMarkup: new InlineKeyboardMarkup(
                            InlineKeyboardButton.WithUrl(
                                "Check sendMessage method",
                                "https://core.telegram.org/bots/api#sendmessage")));
    
                return Ok();
            }
    

    If you want framework to use NewtonsoftJson instead of default Json Utility (which is not necessary in your case), please follow this instructions https://dotnetcoretutorials.com/2019/12/19/using-newtonsoft-json-in-net-core-3-projects/