Reputation: 1639
I have some 3rd party data provider with a nested data structure like this
{
"response": {
"...": "...",
"transactions": [
{
"well-known-field": 123,
"new-unknown-field": 456,
}
]
}
}
So, I have a corresponding class structure for deserialization. On a transaction level the class have only well-known fields. But on each transaction there are some dynamic fields or just new fields that I prefer to have at least in logs or even in mongodb document. I known I can put JRaw
for any of those fields, but I don't know the names of future fields and I just prefer to have full raw transaction itself. Is it possible to have additional JObject
of transaction itself inside Transaction
class?
I suppose, I can do this by deserializing via second data structure where List of transactions is just a List<JObject>
and then just go foreach transaction in first result and set a JObject Raw
field from second result but that looks silly. May be there are some extension or built-in ability to achieve that in Newtonsoft JSON.Net in one pass?
public class Transaction
{
public decimal WellKnownField { get; set; }
public JObject RawTransaction { get; set; }
}
UPD: I think I'd better prefer string RawTransaction
instead. That would be perfect for serialization diagnostics, for logging original raw json and for attempts to re-apply serialization itself in case if we change some attributes or settings, or default values.
Upvotes: 3
Views: 1785
Reputation: 1639
This is what I eventually came up with:
public class TransactionResponse
{
[JsonExtensionData]
[JsonIgnore]
public JObject AdditionalData { get; set; }
[JsonIgnore]
public JValue RawTransaction { get; set; }
[OnDeserialized]
internal void OnDeserialized(StreamingContext ctx)
{
var ser = (JValue)JsonConvert.SerializeObject(this);
AdditionalData.Merge(ser);
RawTransaction = ser;
}
public decimal Amount { get; set; }
That gives a full view of original object, and I can even put it to mongo as a string using RawTransaction.ToString()
for any future analysis. Not perfect because it is tokenized and I don't see the original whitespaces and cr lf in json but that's probably too much...
Upvotes: 1
Reputation: 5755
I would recommend you to make your Transaction
class look like this:
public class Transaction {
[JsonProperty("id")]
public String Id {get; set;}
[JsonProperty("amount")]
public decimal Amount {get; set;}
...
[JsonExtensionData]
public Dictionary<String,Object> AdditionalData {get; set;}
}
This way you can both benefit from Strongly Typed
information which are known at compile time and those which are dynamic.
Upvotes: 5