最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - How to create a custom Json.NET converter to return a Json string that contains Json stored in the object being serialized

programmeradmin2浏览0评论

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 to mergeResp.ApiResponse1.OrigJson
  • api_response2 property value set to mergeResp.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 to mergeResp.ApiResponse1.OrigJson
  • api_response2 property value set to mergeResp.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
  • Add some [JsonExtensionData] IDictionary<string, JToken> additionalData; property to ApiResponse1 and ApiResponse2 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
Add a comment  | 

1 Answer 1

Reset to default 0

I 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}"
  }}

与本文相关的文章

发布评论

评论列表(0)

  1. 暂无评论