I'm working with SwiftType Elastic Search + C# and running into an issue deserializing the response due to the fact that SwiftType returns all of the fields as objects with a raw
property (https://swiftype.com/documentation/app-search/api/search) for example:
{
"meta": {
"warnings": [],
"page": {
"current": 1,
"total_pages": 1,
"total_results": 2,
"size": 10
},
"request_id": "6887a53f701a59574a0f3a7012e01aa8"
},
"results": [
{
"phone": {
"raw": 3148304280.0
},
"accounts_balance_ach": {
"raw": 27068128.71
},
"accounts_balance_pending": {
"raw": "46809195.64"
},
"email": {
"raw": "[email protected]"
},
"accounts_count": {
"raw": 6.0
},
"id": {
"raw": "c98808a2-d7d6-4444-834d-2fe4f6858f6b"
},
"display_name": {
"raw": "The Johnstons"
},
"type": {
"raw": "Couple"
},
"advisor_email": {
"raw": "[email protected]"
},
"created_at": {
"raw": "2018-10-02T10:42:07+00:00"
},
"source": {
"raw": "event"
},
"accounts_balance": {
"raw": 43629003.47
},
"accounts_donations": {
"raw": 38012278.75
},
"advisor_name": {
"raw": "Cloyd Jakubowski"
},
"_meta": {
"score": 0.42934617
}
},
{
"phone": {
"raw": 2272918612.0
},
"accounts_balance_ach": {
"raw": 35721452.35
},
"accounts_balance_pending": {
"raw": "35117465.2"
},
"email": {
"raw": "[email protected]"
},
"accounts_count": {
"raw": 1.0
},
"id": {
"raw": "687af11f-0f73-4112-879c-1108303cb07a"
},
"display_name": {
"raw": "Kennith Johnston"
},
"type": {
"raw": "Individual"
},
"advisor_email": {
"raw": "[email protected]"
},
"created_at": {
"raw": "2018-10-02T16:16:02+00:00"
},
"source": {
"raw": "website"
},
"accounts_balance": {
"raw": 23063874.19
},
"accounts_donations": {
"raw": 33025175.79
},
"advisor_name": {
"raw": "Ernie Mertz"
},
"_meta": {
"score": 0.39096162
}
}
]
}
I need to map each key to its value, eg results[0].email = "[email protected]";
I saw a promising option with custom converters but I want to make sure there is not a more dynamic way to do this before I take the verbose approach.
I would suggest using the JsonPathConverter
class found in Can I specify a path in an attribute to map a property in my class to a child property in my JSON?. This will allow you to declare a strongly-typed Result
class and then easily map each of the properties to the value of the respective raw
child value in the JSON without having to declare a ton of awkward single-property classes.
Declare your model as shown below. Note that the Result
class needs a [JsonConverter]
attribute on it to tie it to the JsonPathConverter
(otherwise the property paths will not work and you will get default values in your properties).
public class RootObject
{
public List<Result> results { get; set; }
}
[JsonConverter(typeof(JsonPathConverter))]
public class Result
{
[JsonProperty("phone.raw")]
public string Phone { get; set; }
[JsonProperty("accounts_balance_ach.raw")]
public decimal AccountsBalanceAch { get; set; }
[JsonProperty("accounts_balance_pending.raw")]
public decimal AccountsBalancePending { get; set; }
[JsonProperty("email.raw")]
public string Email { get; set; }
[JsonProperty("accounts_count.raw")]
public decimal AccountsCount { get; set; }
[JsonProperty("id.raw")]
public string Id { get; set; }
[JsonProperty("display_name.raw")]
public string DisplayName { get; set; }
[JsonProperty("type.raw")]
public string Type { get; set; }
[JsonProperty("advisor_email.raw")]
public string AdvisorEmail { get; set; }
[JsonProperty("created_at.raw")]
public string CreatedAt { get; set; }
[JsonProperty("source.raw")]
public string Source { get; set; }
[JsonProperty("accounts_balance.raw")]
public decimal AccountsBalance { get; set; }
[JsonProperty("accounts_donations.raw")]
public decimal AccountsDonations { get; set; }
[JsonProperty("advisor_name.raw")]
public string AdvisorName { get; set; }
[JsonProperty("_meta.score")]
public decimal MetaScore { get; set; }
}
Then you can just deserialize as usual:
var root = JsonConvert.DeserializeObject<RootObject>(json);
Here is a working demo: https://dotnetfiddle.net/wYxwIF
The Most dynamic way for you would be to use The Newtonsoft JObejct class.
It will parse your JSON string into a JSON object for you to use, this is if you do not have a corresponding model and you need to create a dynamic JSON object.
For example:
string json = "{
"meta": {
"warnings": [],
"page": {
"current": 1,
"total_pages": 1,
"total_results": 2,
"size": 10
},
"request_id": "6887a53f701a59574a0f3a7012e01aa8"
},
"results": [
{
"phone": {
"raw": 3148304280.0
},
"accounts_balance_ach": {
"raw": 27068128.71
},
"accounts_balance_pending": {
"raw": "46809195.64"
},
"email": {
"raw": "[email protected]"
},
"accounts_count": {
"raw": 6.0
},
"id": {
"raw": "c98808a2-d7d6-4444-834d-2fe4f6858f6b"
},
"display_name": {
"raw": "The Johnstons"
},
"type": {
"raw": "Couple"
},
"advisor_email": {
"raw": "[email protected]"
},
"created_at": {
"raw": "2018-10-02T10:42:07+00:00"
},
"source": {
"raw": "event"
},
"accounts_balance": {
"raw": 43629003.47
},
"accounts_donations": {
"raw": 38012278.75
},
"advisor_name": {
"raw": "Cloyd Jakubowski"
},
"_meta": {
"score": 0.42934617
}
},
{
"phone": {
"raw": 2272918612.0
},
"accounts_balance_ach": {
"raw": 35721452.35
},
"accounts_balance_pending": {
"raw": "35117465.2"
},
"email": {
"raw": "[email protected]"
},
"accounts_count": {
"raw": 1.0
},
"id": {
"raw": "687af11f-0f73-4112-879c-1108303cb07a"
},
"display_name": {
"raw": "Kennith Johnston"
},
"type": {
"raw": "Individual"
},
"advisor_email": {
"raw": "[email protected]"
},
"created_at": {
"raw": "2018-10-02T16:16:02+00:00"
},
"source": {
"raw": "website"
},
"accounts_balance": {
"raw": 23063874.19
},
"accounts_donations": {
"raw": 33025175.79
},
"advisor_name": {
"raw": "Ernie Mertz"
},
"_meta": {
"score": 0.39096162
}
}
]
}"
JObject result = JObject.Parse(json);
result
is now a JSON object and you can access it's properties.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With