1

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.

Alexander Farber
  • 21,519
  • 75
  • 241
  • 416

2 Answers2

2

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; }
}
Krishna Varma
  • 4,238
  • 2
  • 10
  • 25
  • @Selvin, I didn't understand your point. the OP post is having incorrect model for the response generated by the end point. once he corrects that, the code should work seamlessly – Krishna Varma Jun 30 '23 at 14:23
  • There are already answer on using online code generator ... you may mark it as duplicate ... or wirte the answer by YOURSELF and explain what is wrong with OP code ... – Selvin Jun 30 '23 at 14:26
  • 1
    That is a good hint with "Paste Json as Classes", thank you, I did not know that. I wonder how to detect this mismatch - because `JsonSerializer.Deserialize` (and I also tried `GetFromJsonAsync`) do not throw any exception. – Alexander Farber Jun 30 '23 at 14:41
  • 1
    Thanks Krishna, your suggestion works well, even with reduced members: https://dotnetfiddle.net/ImzJFi – Alexander Farber Jun 30 '23 at 18:28
2

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.

RBee
  • 1,369
  • 6
  • 16
porrokynoa
  • 42
  • 6
  • Is there a way to detect that? There was no exception thrown by the `JsonSerializer.Deserialize` call – Alexander Farber Jun 30 '23 at 14:33
  • It is not a problem of the method of desiarization. Published both the external library and that of C#. Your probbleme is how you have declared the classes. The desierialization method gives you NULL because it does not find a correspondence with your Json and for this you cannot get the data. – porrokynoa Jun 30 '23 at 14:42