I have a C# class called MergeResponse
that contains 3 properties:
- MessageID
- ApiResponse1
- ApiResponse2
ApiResponse1
contains a class object instance that was created by Deserializing Json returned from a 3rd Party External API call.
ApiResponse2
contains a class object instance that was created by Deserializing Json returned from another 3rd Party External API call.
e.g.
string apiResponseJson1 = GetWebData1();
ApiResponse1 apiResponse1 = JsonConvert.DeserializeObject<ApiResponse1>(apiResponseJson1);
string apiResponseJson2 = GetWebData2();
ApiResponse2 apiResponse2 = JsonConvert.DeserializeObject<ApiResponse2>(apiResponseJson2);
MergeResponse mergeResp = new MergeResponse();
mergeResp.MessageId = “1234-5678”;
mergeResp.ApiResponse1 = apiResponse1;
mergeResp.ApiResponse2 = apiResponse2;
The mergeResp
object is then Serialized back to a Json string and stored in the DB.
e.g.
String json = JsonConvert.SerializeObject(mergeResp, Newtonsoft.Json.Formatting.Indented);
The problem is, the Json data returned from the 3rd Party external API’s can change over time and include new properties.
Deserialising and re-serializing only includes properties that are in the ApiResponse1
and ApiResponse2
classes.
I need to store the original Json that was returned by the API’s, including any new properties.
I’ve used the example in the following StackOverFlow post to store the original Json in the apiResponse1
and apiResponse2
objects when the Original API Json is Deserialised:
Storing original JSON string in deserialised JSON.NET objects
The apiResponse1
object stores the Original API Json in a property called apiResponse1.OrigJson
.
And the apiResponse2
object stores the Original API Json in a property called apiResponse2.OrigJson
.
Both OrigJson
properties have the [JsonIgnore()]
attribute to stop them being serialized.
Question
How can I create a custom Newtonsoft Json Converter that returns a Json string with the following property values, when serializing the mergeResp
object :
api_response1
property value set tomergeResp.ApiResponse1.OrigJson
api_response2
property value set tomergeResp.ApiResponse2.OrigJson
e.g.
{
“message_id”: “1234-5678”,
“api_response1”: {
// Include the ApiResponse1.OrigJson value here
},
“api_response2”: {
// Include the ApiResponse2.OrigJson value here
}
}
I have a C# class called MergeResponse
that contains 3 properties:
- MessageID
- ApiResponse1
- ApiResponse2
ApiResponse1
contains a class object instance that was created by Deserializing Json returned from a 3rd Party External API call.
ApiResponse2
contains a class object instance that was created by Deserializing Json returned from another 3rd Party External API call.
e.g.
string apiResponseJson1 = GetWebData1();
ApiResponse1 apiResponse1 = JsonConvert.DeserializeObject<ApiResponse1>(apiResponseJson1);
string apiResponseJson2 = GetWebData2();
ApiResponse2 apiResponse2 = JsonConvert.DeserializeObject<ApiResponse2>(apiResponseJson2);
MergeResponse mergeResp = new MergeResponse();
mergeResp.MessageId = “1234-5678”;
mergeResp.ApiResponse1 = apiResponse1;
mergeResp.ApiResponse2 = apiResponse2;
The mergeResp
object is then Serialized back to a Json string and stored in the DB.
e.g.
String json = JsonConvert.SerializeObject(mergeResp, Newtonsoft.Json.Formatting.Indented);
The problem is, the Json data returned from the 3rd Party external API’s can change over time and include new properties.
Deserialising and re-serializing only includes properties that are in the ApiResponse1
and ApiResponse2
classes.
I need to store the original Json that was returned by the API’s, including any new properties.
I’ve used the example in the following StackOverFlow post to store the original Json in the apiResponse1
and apiResponse2
objects when the Original API Json is Deserialised:
Storing original JSON string in deserialised JSON.NET objects
The apiResponse1
object stores the Original API Json in a property called apiResponse1.OrigJson
.
And the apiResponse2
object stores the Original API Json in a property called apiResponse2.OrigJson
.
Both OrigJson
properties have the [JsonIgnore()]
attribute to stop them being serialized.
Question
How can I create a custom Newtonsoft Json Converter that returns a Json string with the following property values, when serializing the mergeResp
object :
api_response1
property value set tomergeResp.ApiResponse1.OrigJson
api_response2
property value set tomergeResp.ApiResponse2.OrigJson
e.g.
{
“message_id”: “1234-5678”,
“api_response1”: {
// Include the ApiResponse1.OrigJson value here
},
“api_response2”: {
// Include the ApiResponse2.OrigJson value here
}
}
Share
Improve this question
edited Feb 17 at 8:56
m_collard
asked Feb 17 at 0:37
m_collardm_collard
2,0285 gold badges30 silver badges53 bronze badges
1
|
1 Answer
Reset to default 0I think this can help you keep your original JSON from your API Response in your final serialized JSON
public class ApiResponse1JsonConverter : JsonConverter<ApiResponse1>
{
public override ApiResponse1? ReadJson(JsonReader reader, Type objectType, ApiResponse1? existingValue, bool hasExistingValue, JsonSerializer serializer)
{
var jObject = JObject.Load(reader);
// Store original JSON
var originalJson = jObject.ToString();
// Deserialize to our type
var result = jObject.ToObject<ApiResponse1>();
if (result != null)
{
// Store the original JSON
result.OriginalJson = originalJson;
}
return result;
}
public override void WriteJson(JsonWriter writer, ApiResponse1? value, JsonSerializer serializer)
{
var apiResponse = value as ApiResponse1;
if (apiResponse != null && !string.IsNullOrEmpty(apiResponse.OriginalJson))
{
// Write the original JSON directly
writer.WriteRawValue(apiResponse.OriginalJson);
}
else
{
// Fallback to normal serialization
var jObject = JObject.FromObject(value);
jObject.WriteTo(writer);
}
}
}
Sample of using this converter
ApiResponse1 apiResponse1 = JsonConvert.DeserializeObject<ApiResponse1>(response1, new ApiResponse1JsonConverter());
and the result will be like this
{
"MessageId": "123",
"ApiResponse1": {
"Status": "OK",
"Message": "Data is Fetched Successully!",
"OriginalJson": "{\r\n \"status\": \"OK\",\r\n \"message\": \"Data is Fetched Successully!\"\r\n}"
}}
[JsonExtensionData] IDictionary<string, JToken> additionalData;
property toApiResponse1
andApiResponse2
as shown in this answer by cecilphillip to Deserialize json with known and unknown fields. If you do all unknown JSON properties will be captured and re-serialized, and you won't need a converter at all. In fact your question looks like a duplicate, agree? – dbc Commented Feb 17 at 1:27