Alexander Farber
Alexander Farber

Reputation: 22988

JsonSerializer.Deserialize returns an empty object with null properties

I try to parse a response by the OSRM map matching service using the following code (here a .NET Fiddle too; UPDATED with fixed version):

namespace OsrmMapMatch
{
    public class OsrmResponse
    {
        public string code;
        public OsrmLeg[] legs;
    }

    public class OsrmLeg
    {
        public OsrmAnnotation annotation;
    }

    public class OsrmAnnotation
    {
        public uint[] nodes;
    }

    internal class Program
    {
        static async Task Main(string[] args)
        {
            const string HttpClientMapMatch = "HttpClientMapMatch";
            const string OsrmUri = "10.757938,52.437444;10.764379,52.437314;10.770562,52.439067;10.773268,52.436633?overview=simplified&radiuses=50;50;50;50&generate_hints=false&skip_waypoints=true&gaps=ignore&annotations=nodes&geometries=geojson";

            ServiceProvider serviceProvider = new ServiceCollection()
                .AddHttpClient(HttpClientMapMatch, httpClient =>
                {
                    httpClient.BaseAddress = new Uri("https://router.project-osrm.org/match/v1/driving/");
                }).Services.BuildServiceProvider();

            IHttpClientFactory httpClientFactory = serviceProvider.GetService<IHttpClientFactory>();

            HttpClient httpClient = httpClientFactory.CreateClient(HttpClientMapMatch);

            HttpResponseMessage response = await httpClient.GetAsync(OsrmUri);
            if (response.IsSuccessStatusCode) 
            {
                string stringData = await response.Content.ReadAsStringAsync();
                OsrmResponse osrmResponse = JsonSerializer.Deserialize<OsrmResponse>(stringData);
                Console.WriteLine($"OsrmResponse: {JsonSerializer.Serialize(osrmResponse)}");
            }
        }
    }
}

Unfortunately, the returned object is empty, its code and legs properties are null:

VS 2022 screenshot

I have tried the following change with no success:

JsonSerializerOptions options = new()
{
    PropertyNameCaseInsensitive = true
};
OsrmResponse osrmResponse = JsonSerializer.Deserialize<OsrmResponse>(stringData, options);

What could be the reason for the failing JSON parsing?

How do you debug such problems in general?

I would like to use Microsoft's System.Text.Json and do not want to use Newtonsoft.JSON.

I only need the OSM nodes array at the end, that is why I have omitted other members in the response.

Upvotes: 1

Views: 369

Answers (2)

porrokynoa
porrokynoa

Reputation: 208

Your problem is that the Json you want to serialize is different from what you want to deserialize to. You have to fix the class you want your response to deserialize to.

Upvotes: 2

Krishna Varma
Krishna Varma

Reputation: 4260

Based on the response, your model should look like below. The simplest way to generate the model is using Visual Studio->Edit->Paste Special->Paste Json as Classes or any other Online tools like json2csharp. Once you update the model your code should work.

public class Annotation
{
    public List<object> nodes { get; set; }
}

public class Geometry
{
    public List<List<double>> coordinates { get; set; }
    public string type { get; set; }
}

public class Leg
{
    public List<object> steps { get; set; }
    public string summary { get; set; }
    public double weight { get; set; }
    public double duration { get; set; }
    public Annotation annotation { get; set; }
    public double distance { get; set; }
}

public class Matching
{
    public double confidence { get; set; }
    public Geometry geometry { get; set; }
    public List<Leg> legs { get; set; }
    public string weight_name { get; set; }
    public double weight { get; set; }
    public double duration { get; set; }
    public double distance { get; set; }
}

public class OsrmResponse
{
    public string code { get; set; }
    public List<Matching> matchings { get; set; }
}

Upvotes: 2

Related Questions