I'm deliberately trying to create invalid JSON with Newtonsoft Json, in order to place an ESI include tag, which will fetch two more json nodes.
This is my JsonConverter's WriteJson method:
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
mApiResponseClass objectFromApi = (mApiResponseClass)value;
foreach (var obj in objectFromApi.GetType().GetProperties())
{
if (obj.Name == "EsiObj")
{
writer.WriteRawValue(objectFromApi.EsiObj);
}
else
{
writer.WritePropertyName(obj.Name);
serializer.Serialize(writer, obj.GetValue(value, null));
}
}
}
The EsiObj in mApiResponseClass is just a string, but it needs to be written into the JSON response to be interpretted without any property name - so that hte ESI can work.
This of course results in an exception with the Json Writer, with value:
Newtonsoft.Json.JsonWriterException: 'Token Undefined in state Object would result in an invalid JSON object. Path ''.'
Is there any way around this?
An ideal output from this would be JSON formatted, technically not valid, and would look like this:
{
value:7,
string1:"woohoo",
<esi:include src="/something" />
Song:["I am a small API","all i do is run","but from who?","nobody knows"]
}
Edit: Using ESI allows us to have varying cache lengths of a single response - i.e. we can place data that can be cached for a very long time in some parts of the JSON, and only fetch updated parts, such as those that rely on client-specific data. ESI is not HTML specific. (As some state below) It's being run via Varnish, which supports these tags. Unfortunately, it's required that we do only put out 1 file as a response, and require no further request from the Client. We cannot alter our response either - so i can't just add a JSON node specifically to contain the other nodes.
Edit 2: The "more json nodes" part is solved by ESI making a further request to our backend for user/client specific data, i.e. to another endpoint. The expected result is that we then merge the original JSON document and the later requested one together seamlessly. (This way, the original document can be old, and client-specific can be new)
Edit 3: The endpoint /something would output JSON-like fragments like:
teapots:[ {Id: 1, WaterLevel: 100, Temperature: 74, ShortAndStout: true}, {Id: 2, WaterLevel: 47, Temperature: 32, ShortAndStout: true} ],
For a total response of:
{
value:7,
string1:"woohoo",
teapots:[ {Id: 1, WaterLevel: 100, Temperature: 74, ShortAndStout: true}, {Id: 2, WaterLevel: 47, Temperature: 32, ShortAndStout: true} ],
Song:["I am a small API","all i do is run","but from who?","nobody knows"]
}