I'm trying to consume Event Espresso 4 (EE4) REST API in my Xamarin forms app. The DTO that I receive (as JSON) from EE4 REST API is fairly complicated and I would like to flatten it into my "fairly simple" model that I will be using within the app.
The DTO that I receive from EE4 REST API looks as follows:
[
{
"ATT_ID": 10686,
"ATT_full_name": "Four Nights",
"ATT_fname": "Four",
"ATT_lname": "Nights",
"ATT_email": "four.nights@yopmail.com",
"ATT_phone": "+18001579534565",
"registrations": [
{
"REG_ID": 183,
"EVT_ID": 10584,
"ATT_ID": 10686,
"TXN_ID": 66,
"TKT_ID": 4,
"STS_ID": "RAP",
"REG_date": "2019-02-13T09:30:00",
"REG_code": "66-4-1-24bf",
"REG_count": 1,
"REG_group_size": 1,
"REG_date_gmt": "2019-02-13T08:30:00",
"_calculated_fields": {
"_protected": []
},
"transaction": {
"TXN_ID": 66,
"STS_ID": "TCM",
"payments": [
{
"PAY_ID": 20,
"TXN_ID": 66,
"STS_ID": "PAP",
"PMD_ID": 11
}
]
},
"answers": [
{
"ANS_ID": 112,
"ANS_value": "Male",
"question": {
"QST_ID": 11,
"QST_display_text": {
"raw": "Gender",
"rendered": "<p>Gender</p>\n"
}
}
},
{
"ANS_ID": 113,
"ANS_value": [
"Double Occupancy"
],
"question": {
"QST_ID": 12,
"QST_display_text": {
"raw": "Room Type",
"rendered": "<p>Room Type</p>\n"
}
}
},
{
"ANS_ID": 114,
"ANS_value": "None",
"question": {
"QST_ID": 13,
"QST_display_text": {
"raw": "Who would you like to share your room with?",
"rendered": "<p>Who would you like to share your room with?</p>\n"
}
}
}
]
}
]
}
]
The C# equivalent that I have in my project is here.
My simple C# object looks as follows:
public class Attendee : RealmObject
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public string Type { get; set; }
public int RegistrationId { get; set; }
public string RegistrationCode { get; set; }
public string RegistrationStatus { get; set; }
public DateTimeOffset RegistrationDate { get; set; }
public DateTimeOffset RegistrationDateGMT { get; set; }
public long EventId { get; set; }
public long TicketId { get; set; }
public long GroupCount { get; set; }
public long TransactionId { get; set; }
public string TransactionStatus { get; set; }
public long PaymentId { get; set; }
public string PaymentStatus { get; set; }
public string CheckedIn { get; set; }
public Attendee()
{
}
}
I've tried different things like ForMember and ForPath. I have also tried mapping the internal objects to the simple one but I keep getting the following error:
AutoMapper.AutoMapperConfigurationException:
Unmapped members were found. Review the types and members below.
Add a custom mapping expression, ignore, add a custom resolver, or modify the source/destination type
For no matching constructor, add a no-arg ctor, add optional arguments, or map all of the constructor parameters
===================================================
AutoMapper created this type map for you, but your types cannot be mapped using the current configuration.
Char -> Attendee (Destination member list)
System.Char -> Organizer.Models.Attendees.Attendee (Destination member list)
Unmapped properties:
Id
FirstName
LastName
FullName
Email
Phone
Type
RegistrationId
RegistrationCode
RegistrationStatus
RegistrationDate
RegistrationDateGMT
EventId
TicketId
GroupCount
TransactionId
TransactionStatus
PaymentId
PaymentStatus
CheckedIn
I appreciate any help I could get on the mapping them.
Thanks
EDIT:
In the same project I have to following JSON and C# objects and mapping configuration and although the objects are different, the mappings work perfectly well.
JSON Object from EE4 REST API
[
{
"EVT_ID": 10584,
"EVT_name": "Mamboland Milano 2019",
"status": {
"raw": "publish",
"pretty": "Published"
},
"EVT_visible_on": "2019-01-26T16:11:04",
"datetimes": [
{
"DTT_ID": 1,
"DTT_EVT_start": "2019-04-04T12:00:00",
"DTT_EVT_end": "2019-04-08T04:00:00"
}
]
}
]
My C# Object
public class Event
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
public string Status { get; set; }
public int DateTimeID { get; set; }
public DateTimeOffset Start { get; set; }
public DateTimeOffset End { get; set; }
public string VLogo { get; set; }
public string HLogo { get; set; }
public Event()
{
}
}
Automapper Mapping configuration for the above:
#region Event Mappings
//Inner Class Status
CreateMap<DTOs.Status, Models.Event>()
.ForMember(d => d.Status, o => o.MapFrom(s => s.Pretty))
.ReverseMap();
//Inner Class Datetime
CreateMap<DTOs.Datetime, Models.Event>()
.ForMember(d => d.DateTimeID, o => o.MapFrom(s => s.Id))
.ForMember(d => d.Start, o => o.MapFrom(s => s.Start))
.ForMember(d => d.End, o => o.MapFrom(s => s.End))
.ReverseMap();
//Outer Class
CreateMap<DTOs.Event, Models.Event>()
.ForMember(d => d.Id, o => o.MapFrom(s => s.Id))
.ForMember(d => d.Name, o => o.MapFrom(s => s.Name))
.ForMember(d => d.City, o => o.Ignore())
.ForMember(d => d.Status, o => o.MapFrom(s => s.Status.Pretty))
.ForMember(d => d.DateTimeID, o => o.MapFrom(s => s.Datetimes.ToList().FirstOrDefault().Id))
.ForMember(d => d.Start, o => o.MapFrom(s => s.Datetimes.ToList().FirstOrDefault().Start))
.ForMember(d => d.End, o => o.MapFrom(s => s.Datetimes.ToList().FirstOrDefault().End))
.ForMember(d => d.VLogo, o => o.Ignore())
.ForMember(d => d.Id, o => o.Ignore())
.ReverseMap();
#endregion
As you can see, I have had to first map the inner classes and then map the outer classes and in doing so, I have been able to generate my c# objects just by mapping.