Full Error: InvalidOperationException: Cannot get the value of a token type 'Number' as a string. System.Text.Json.Utf8JsonReader.GetString()
JsonException: The JSON value could not be converted to System.String. Path: $[0].status | LineNumber: 0 | BytePositionInLine: 197. System.Text.Json.ThrowHelper.ReThrowWithPath(ref ReadStack state, ref Utf8JsonReader reader, Exception ex)
I have MVC project that is trying consume Web API that is working correctly. Now, there is HouseController.cs
using Microsoft.AspNetCore.Mvc;
using Task3.Controllers.Services;
namespace Task3.Controllers;
public class HouseController : Controller
{
private readonly IHouseService _service;
public HouseController(IHouseService service)
{
_service = service ?? throw new ArgumentNullException(nameof(service));
}
public async Task<IActionResult> Index()
{
var houses = await _service.Find();
return View(houses);
}
}
that is calling Find()
method in interface IHouseService
using Task3.Models;
namespace Task3.Controllers.Services
{
public interface IHouseService
{
Task<IEnumerable<HouseModel>> Find();
}
}
that in its turn calls the same method in HouseService.cs
using Task3.Controllers.Helper;
using Task3.Models;
namespace Task3.Controllers.Services
{
public class HouseService : IHouseService
{
private readonly HttpClient _client;
public const string BasePath = "/api/Houses";
public HouseService(HttpClient client)
{
_client = client ?? throw new ArgumentNullException(nameof(client));
}
public async Task<IEnumerable<HouseModel>> Find()
{
var response = await _client.GetAsync(BasePath);
return await response.ReadContentAsync<List<HouseModel>>();
}
}
}
which calls ReadContentAsync<List<HouseModel>>()
using Newtonsoft.Json;
using JsonSerializer = System.Text.Json.JsonSerializer;
namespace Task3.Controllers.Helper
{
public static class HttpClientExtensions
{
public static async Task<T> ReadContentAsync<T>(this HttpResponseMessage response)
{
if (response.IsSuccessStatusCode == false)
throw new ApplicationException($"Something went wrong calling the API: {response.ReasonPhrase}");
var dataAsString = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
Console.WriteLine(dataAsString);
var result = JsonSerializer.Deserialize<T>(dataAsString);
return result;
}
}
}
and the line with Deserialize<T>
returns the before mentioned error.
What I tried is obviously debugging, the Deserialize<T>
method, besides returning error, returns null 'cause it apparently cannot convert Json result to Model attributes. Here is HouseModel
namespace Task3.Models;
public class HouseModel
{
public string Price { get; set; }
public string Region { get; set; }
public string PublicationDate { get; set; }
public string GeoLat { get; set; }
public string GeoLon { get; set; }
public string BuildingType { get; set; }
public string Area { get; set; }
public string Rooms { get; set; }
public string FloorNum { get; set; }
public string TotalFloor { get; set; }
public string ObjectType { get; set; }
public string Id { get; set; }
public string status { get; set; }
public string Photo { get; set; }
}
Btw, before that HouseModel
attributes were int, DateTime etc. and the error was cannot convert to Int32.
Also I used custom Converter StringConverter
public class StringConverter : System.Text.Json.Serialization.JsonConverter<string>
{
public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
if (reader.TokenType == JsonTokenType.Number)
{
var stringValue = reader.GetInt32();
stringValue = stringValue;
return stringValue.ToString();
}
else if (reader.TokenType == JsonTokenType.String)
{
return reader.GetString();
}
throw new System.Text.Json.JsonException();
}
public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options)
{
writer.WriteStringValue(value);
}
}
but in that case every entry is null
.
Can anybody share some insight?