I'm working on a .NET Core application that utilizes EventBrite's API. Within the EventBrite API, many result sets are paginated. My use case requires me to retrieve the full results for multiple sets of data - Events, Attendees, etc.
Rather than have the same logic to handle each Paginated result set, I figured I could create a generic method to loop through the paginated results and get my results back - something like the following.
private List<T> GetPaginatedResult<T>(string path) where T : class
{
var firstResult = GetEventBriteResult<PaginatedResponse<T>>(path);
var pages = firstResult.Pagination.page_count;
var results = firstResult.Objects;
if (pages > 1)
{
for (int i = 1; i < pages; i++)
{
var paginatedPath = path + $"?page={i + 1}";
var paginatedResult = GetEventBriteResult<PaginatedResponse<T>>(paginatedPath);
results.AddRange(paginatedResult.Objects);
}
}
return results;
}
Each of the EventBrite result sets contains a 'Pagination' object, as well as the list of the current pages datasets.
I created a class to handle the Paginated results, where the EventBritePagination
class matches the EventBrite class to handle pagination. The Objects
property is where I'm having issues.
public class PaginatedResponse<T> where T : class
{
public EventBritePagination Pagination { get; set; } = new EventBritePagination();
public virtual List<T> Objects { get; set; } = new List<T>();
}
The issue is that EventBrite has custom naming conventions for each of their classes. For example, looking at the 'Event' class and the 'Attendee' class, they would look like the following if I had built them out manually.
public class EventBriteEvent {
EventBritePagination Pagination { get; set; }
List<Event> Events { get; set; }
}
public class EventBriteAttendee {
EventBritePagination Pagination { get; set; }
List<Attendee> Attendees { get; set; }
}
Each class has the 'Pagination' object, but the Properties I'm attempting to map to the list of 'Objects' has a different name for each object type.
So when I go to deserialize the response, I end up needing to define multiple JsonPropertyNames in order to facilitate the fact that my Objects
property may be named 'attendees' or 'events' or similar.
I know there's got to be a better way to do this with Generic types, but they aren't my strong suit.
Is there a way that I can define a class with a Generic property that can deserialize from a variety of JsonPropertyNames? Or a way to achieve the end goal with another method of inheritance?
Edit 1
For abundance of clarity, this is what the actual JSON response from EventBrite looks like.
First, the result for Attendees
{
"pagination": {
"page_number": 1,
"page_count": 1
},
"attendees": [
{ "first" : "Jeff", ... },
{ "first" : "John", ... }
]
And secondly, the Events...
{
"pagination": {
"page_number": 1,
"page_count": 1
},
"events": [
{ "name" : "Anime NebrasKon 2014", ... },
{ "name" : "Anime NebrasKon 2015", ... }
]
Both responses contain the 'Pagination' property, but differing second attributes. The second attribute will always be a List of objects, however.
My goal is to build a reusable method where I can grab either the Attendees or the Events (or any of the paginated results from EventBrite)
The biggest issue is that because the secondary attributes are named differently, I can't reference the specific secondary attribute that I need to - and if I keep it generic, as a List<T> Objects
, then I can't deserialize the Objects list using JsonPropertyNames
, as I can only specify one name, not multiple.