Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

348
Views
In Json.Net's JsonConverter<> ReadJson(), why is reader..Value null?

I'm trying to write a custom JsonConverter for NetTopologySuite geometries.

My model:

public class MyModel
{
    public string myName { get; set; }

    [JsonConverter(typeof(MyPolygonConverter))]
    public Polygon myPolygon { get; set; }
}

My converter:

public class MyPolygonConverter : JsonConverter<Polygon>
{
    public override Polygon ReadJson(JsonReader reader, Type objectType, Polygon existingValue, 
        bool hasExistingValue, JsonSerializer serializer)
    {
        var geoJson = (string)reader.Value;

        // ... not relevant, because reader.Value is null.
    }
}

What I'm doing:

var deSerialized = JsonConvert.DeserializeObject<MyModel>("{\"myName\":\"My Name\",\"myPolygon\":{\"type\":\"Polygon\",\"coordinates\":[[[-100.0,45.0],[-98.0,45.0],[-99.0,46.0],[-100.0,45.0]]]}}");

And what's happening:

My converter is being called, but reader.Value is null.

The examples I've seen online use (string)reader.Value to access the json string that needs to be converted. But in my case reader.Value is null.

How am I supposed to access the JSON string I need to convert?

To be clear - what I have is a model class that contains a property of a class - Polygon - that I convert to GeoJson on serialization that I need to convert back to that class, from the GeoJson.

So, my starting json is:

{
    "myName" : "My Name",
    "myPolygon" : {
        "type" : "Polygon",
        "coordinates" : [
            [
                [-100.0, 45.0],
                [-98.0, 45.0],
                [-99.0, 46.0],
                [-100.0, 45.0]
            ]
        ]
    }
}

And I need to take everything that a child of "myPolygon" and hand it off to my conversion code. In the simple examples I've seen, reader.Value provided the value as a string. In this case it does not, most likely because "myPolygon"'s child isn't a single value, but is instead a complex json object.

I already have code for parsing the value when provided as a single json string. So how can I get the child, as a single json string?

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

I think you have a misconception about how JsonConverters work. The reader does not give you the raw JSON. Instead it allows you to step through the tokens in the JSON one by one.

reader.Value is null because your converter is handling an object, not a string, and at the point your converter is called, the reader is positioned on the StartObject token. You need to call reader.Read() in a loop to advance through the object to get the property names and values until you reach the EndObject token.

Here is a fiddle that demonstrates that process, although it doesn't actually populate the Polygon. https://dotnetfiddle.net/MQE6N5

If you really want the JSON string inside the converter, you could load a JObject from the reader, and then call its ToString() method:

public override Polygon ReadJson(JsonReader reader, Type objectType, Polygon existingValue, bool hasExistingValue, JsonSerializer serializer)
{
    JObject jo = JObject.Load(reader);
    string json = jo.ToString(Formatting.None);

    Polygon poly = ConvertJsonToPolygon(json);  // your conversion method
    
    return poly;
}

A better solution IMO is to use the facilities of the JObject to actually do the conversion. You can easily pick values out of the JObject and populate your Polygon class from it:

public override Polygon ReadJson(JsonReader reader, Type objectType, Polygon existingValue, bool hasExistingValue, JsonSerializer serializer)
{
    JObject jo = JObject.Load(reader);
    Polygon poly = new Polygon();
    poly.type = (string)jo["type"];
    poly.coordinates = jo["coordinates"].ToObject<double[][][]>(serializer);
    return poly;
}

Fiddle: https://dotnetfiddle.net/OFSP1h

over 4 years ago · Santiago Trujillo Report

0

As Brian Rogers pointed out, I was looking at things incorrectly.

But I really didn't want to have to loop through the JsonReader, one token at a time, to build up the json object I need to process.

Fortunately, I don't have to. Json.Net already provides tools to do this:

public override Polygon ReadJson(JsonReader reader, Type objectType, 
    Polygon existingValue, bool hasExistingValue, JsonSerializer serializer)
{
    var jObject = JObject.Load(reader);
    var geoJson = jObject.ToString();

    // Work with the geoJson string...
}

Note - this works when the object is not an array, which it will never be in my use case. If you're doing something where it is, you might need to use JArray instead. If your use case provides that your object might be an array or an object, you might be able to distinguish which you need to use by checking if reader.TokenType == JsonToken.StartObject. I've not explored that, because it's not possible in my use case.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!