Json.net map dynamic property to a fixed one [dupl

2019-07-23 21:42发布

QuickBooks Online uses for their API the following response:

{
  "QueryResponse": {
    "Customer": [
      {
        "GivenName": "Test"
      },
      {
        "GivenName": "Test 2"
      }
    ],
    "startPosition": 1,
    "maxResults": 2
  },
  "time": "2018-08-11T16:12:10.808-07:00"
}

I'm trying to create a C# model from this:

public class QueryResponseRoot<T> where T : IQuickbooksBaseEntity
{
    [JsonProperty("QueryResponse")]
    public QueryResponse<T> QueryResponse { get; set; }

    [JsonProperty("time", Required = Required.Always)]
    public DateTimeOffset Time { get; set; }
}

public class QueryResponse<T> where T : IQuickbooksBaseEntity
{
    [JsonProperty, JsonConverter(typeof(QuickbooksResponseConverter))]
    public IList<T> Results { get; set; }

    [JsonProperty("startPosition")]
    public Int64 StartPositions { get; set; }

    [JsonProperty("maxResults")]
    public Int64 MaxResults { get; set; }
}

The API has multiple entities which are all defined with the IQuickbooksBaseEntity interface.

The problem is that if you get Customers it will return Customer as a property on the QueryResponse object, but if you get something else like Accounts the response looks like this:

{
  "QueryResponse": {
    "Account": [
      {
        "Name": "Accounts Payable (A/P)"
      }
    ],
    "startPosition": 1,
    "maxResults": 90
  },
  "time": "2018-08-11T16:14:55.309-07:00"
}

How can I map the property Customer or Account or any other one from a known list to the Results property in my model?

Import to know (probably) is that I do know when I call the API which property will be returned to me (i.e. Customer or Account).

Now I'm solving it directly in code, but I'm not sure if casting it dynamic has large performance issues:

var resultObjectJson = JsonConvert.DeserializeObject<dynamic>(body);

var entityName = typeof(T).Name;

var maxResults = (Int64) resultObjectJson.QueryResponse.maxResults;
var startPositions = (Int64) resultObjectJson.QueryResponse.startPosition;
var results = ((JArray) resultObjectJson.QueryResponse[entityName]).ToObject<List<T>>();

var resultRoot = new QueryResponseRoot<T>
{
    QueryResponse = new QueryResponse<T>
    {
        MaxResults = maxResults,
        StartPositions = startPositions,
        Results = results
    }
};

return resultRoot.QueryResponse;

标签: json.net
0条回答
登录 后发表回答