Вопрос
Я разрабатываю службу бронирования квартир, которая собирает данные из нескольких поставщиков с подробностями внешней квартиры. Каждый поставщик предоставляет корпус ответа, содержащий информацию о недвижимости, включая список доступных комнат. Моя цель - превратить эти разнообразные ответы поставщиков в единый формат «Ответ на бронирование квартир». Это несколько номеров, доступных под одним идентификатором. Но когда я пытаюсь преобразовать все детали, связанные с комнатой в детали поиска в квартире, детали, связанные с помещением, не отображаются. < /P>
ApartmentResponseDTO.Models< /code> (классы DTO) < /p>
Определяет объекты передачи данных для ответа на поиск квартир.namespace ApartmentResponseDTO.Models
{
public class ApartmentSearchResponseDTO
{
public List Results { get; set; }
public MetaDto Meta { get; set; }
}
public class ApartmentResultDTO
{
public int PropertyId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public LocationDto Location { get; set; }
public int StarRating { get; set; }
public List Amenities { get; set; }
public List Images { get; set; }
public CancellationPolicyDto CancellationPolicy { get; set; }
public PriceDto Price { get; set; }
public SupplierDetailsDto SupplierDetails { get; set; }
public List Rooms { get; set; }
}
public class LocationDto
{
public double Lat { get; set; }
public double Lon { get; set; }
}
public class CancellationPolicyDto
{
public string FreeCancellationUntil { get; set; }
public string Type { get; set; }
}
public class PriceDto
{
public float NetRate { get; set; }
public float FinalRate { get; set; }
public string Currency { get; set; }
}
public class SupplierDetailsDto
{
public string SupplierId { get; set; }
public string RawSupplierId { get; set; }
}
public class MetaDto
{
public int TotalResults { get; set; }
public int Page { get; set; }
public int PageSize { get; set; }
}
public class RoomDto
{
public string RoomId { get; set; }
public int NoOfAdults { get; set; }
public RoomPriceDto Price { get; set; }
public RoomPoliciesDto Policies { get; set; }
}
public class RoomPriceDto
{
public float NetPrice { get; set; }
public float GrossPrice { get set; }
public float TotalPrice { get; set; }
}
public class RoomPoliciesDto
{
public RoomCancellationDto Cancellation { get; set; }
}
public class RoomCancellationDto
{
public string FreeCancellationUntil { get; set; }
public string Type { get; set; }
public List PaymentTimings { get; set; }
}
}
< /code>
ApartmentDetailsResponseDTO.Models (классы DTO):
служит промежуточным форматом во время процесса преобразования.
public class ApartmentDetailsResponseDTO
{
public int PropertyId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public int StarRating { get; set; }
public List Amenities { get; set; }
public List Images { get; set; }
public double Lat { get; set; }
public double Lon { get set; }
public string FreeCancellationUntil { get; set; }
public string Type { get; set; }
public float NetRate { get; set; }
public float FinalRate { get; set; }
public string Currency { get; set; }
public string RoomId { get; set; }
public int NoOfAdults { get; set; }
public float NetPrice { get; set; }
public float GrossPrice { get; set; }
public float TotalPrice { get; set; }
public string RoomFreeCancellationUntil { get; set; }
public string RoomType { get; set; }
public List PaymentTimings { get; set; }
}
< /code>
responseMapping.json:
{
"ResponseMapper": "{\"PROPERTY_ID\": [ \"properties[0].propertyId\", \"property_id\", \"data[0].id\" ], \"NAME\": [ \"properties[0].propertyName\", \"rooms[0].room_name\", null ], \"ADDRESS\": [ null, null, null ], \"STAR_RATING\": [ \"properties[0].star_rating\", null, null ], \"AMENITIES\": [ \"properties[0].rooms[0].benefits[*].benefitName\", \"rooms[0].rates[0].amenities.*.name\", null ], \"IMAGES\": [ null, null, null ], \"LAT\": [ null, null, null ], \"LON\": [ null, null, null ], \"CANCELLATION_POLICY_FREE_CANCELLATION_UNTIL\": [ \"properties[0].rooms[0].cancellationPolicy.date[0].before\", \"rooms[0].rates[0].cancel_penalties[0].start\", \"data[0].products[0].policies.cancellation.free_cancellation_until\" ], \"CANCELLATION_POLICY_TYPE\": [ \"properties[0].rooms[0].cancellationPolicy.code\", \"rooms[0].rates[0].refundable\", \"data[0].products[0].policies.cancellation.type\" ], \"PRICE_NET_RATE\": [ \"properties[0].rooms[0].rate.exclusive\", \"rooms[0].rates[0].occupancy_pricing['1'].totals.exclusive.request_currency.value\", \"data[0].price.base\" ], \"PRICE_FINAL_RATE\": [ \"properties[0].rooms[0].rate.inclusive\", \"rooms[0].rates[0].occupancy_pricing['1'].totals.inclusive.request_currency.value\", \"data[0].price.book\" ], \"PRICE_CURRENCY\": [ \"properties[0].rooms[0].rate.currency\", \"rooms[0].rates[0].occupancy_pricing['1'].totals.inclusive.request_currency.currency\", \"data[0].currency\" ], \"ROOM_ID\": [ \"properties[0].rooms[0].roomId\", \"rooms[0].id\", \"data[0].products[0].room\" ], \"NO_OF_ADULTS\": [ \"properties[0].rooms[0].normalBedding\", \"rooms[0].no_of_adults\", \"data[0].products[0].number_of_adults\" ], \"ROOM_PRICE_NET_PRICE\": [ \"properties[0].rooms[0].rate.exclusive\", \"rooms[0].rates[0].occupancy_pricing['1'].totals.exclusive.request_currency.value\", \"data[0].products[0].price.base\" ], \"ROOM_PRICE_GROSS_PRICE\": [ \"properties[0].rooms[0].rate.inclusive\", \"rooms[0].rates[0].occupancy_pricing['1'].totals.inclusive.request_currency.value\", \"data[0].products[0].price.book\" ], \"ROOM_PRICE_TOTAL_PRICE\": [ \"properties[0].rooms[0].totalPayment.inclusive\", \"rooms[0].rates[0].occupancy_pricing['1'].totals.property_inclusive.request_currency.value\", \"data[0].products[0].price.total\" ], \"ROOM_FREE_CANCELLATION_UNTIL\": [ \"properties[0].rooms[0].cancellationPolicy.date[0].before\", \"rooms[0].rates[0].cancel_penalties[0].start\", \"data[0].products[0].policies.cancellation.free_cancellation_until\" ], \"ROOM_TYPE\": [ \"properties[0].rooms[0].cancellationPolicy.code\", \"rooms[0].rates[0].refundable\", \"data[0].products[0].policies.cancellation.type\" ], \"ROOM_PAYMENT_TIMINGS\": [ \"properties[0].rooms[0].cancellationPolicy.parameter\", \"rooms[0].rates[0].cancel_penalties[0].parameter\", \"data[0].products[0].policies.payment.timings\" ]}"
}
< /code>
StringSupplierResponseTransformer.cs:
преобразует ответы поставщика в Unified Apartmentsearchresponsedto формат.
использует конфигурацию отображения для извлечения и карты данных.
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using ApartmentResponseDTO;
using ApartmentResponseDTO.Models;
public class SupplierResponseTransformer
{
private readonly JObject _responseMappings;
public SupplierResponseTransformer(string responseMappingsFile)
{
string mappingsJson = File.ReadAllText(responseMappingsFile).Trim();
JObject mappingsObject = JObject.Parse(mappingsJson);
string responseMapperString = mappingsObject["ResponseMapper"].ToString();
_responseMappings = JObject.Parse(responseMapperString);
}
public SupplierResponseTransformer(JObject responseMappings)
{
_responseMappings = responseMappings;
}
public async Task TransformResponseAsync()
{
string supplierResponseString = @"[
{
""searchId"": 162918320,
""properties"": [
{
""propertyId"": 12157,
""propertyName"": ""Medhufushi Island Resort"",
""translatedPropertyName"": ""Medhufushi Island Resort"",
""rooms"": [
{
""roomId"": 3134585,
""blockId"": ""YmNlMTU5MzctOjMzMg=="",
""roomName"": ""2 Bedroom Beach Suite"",
""ratePlanId"": 617126,
""freeWifi"": false,
""totalPayment"": {
""exclusive"": 667.68,
""inclusive"": 822.58,
""tax"": 114.29,
""fees"": 0,
""estimatedCommission"": 32.9
}
},
{
""roomId"": 3134585,
""blockId"": ""YmNlMTU5MzctOjMzMg=="",
""roomName"": ""2 Bedroom Beach Suite"",
""ratePlanId"": 617126,
""freeWifi"": false,
""totalPayment"": {
""exclusive"": 667.68,
""inclusive"": 822.58,
""tax"": 114.29,
""fees"": 0,
""estimatedCommission"": 32.9
}
}
]
}
]
}
]";
JToken supplierData = JToken.Parse(supplierResponseString);
if (supplierData.Type == JTokenType.Array)
{
var tasks = supplierData.Select(supplierEntry => Task.Run(() => TransformSupplierResponse(supplierEntry)))
.ToList();
var responses = await Task.WhenAll(tasks);
return responses.ToList();
}
else if (supplierData.Type == JTokenType.Object)
{
var transformedResponse = TransformSupplierResponse(supplierData);
return new List { transformedResponse };
}
else
{
throw new JsonReaderException("Unexpected JSON format");
}
}
private ApartmentSearchResponseDTO TransformSupplierResponse(JToken supplierEntry)
{
var apartmentDetails = new ApartmentDetailsResponseDTO
{
PropertyId = GetValue(supplierEntry, "PROPERTY_ID"),
Name = GetValue(supplierEntry, "NAME"),
Address = GetValue(supplierEntry, "ADDRESS"),
StarRating = GetValue(supplierEntry, "STAR_RATING"),
Amenities = GetValue(supplierEntry, "AMENITIES"),
Images = GetValue(supplierEntry, "IMAGES"),
Lat = GetValue(supplierEntry, "LAT"),
Lon = GetValue(supplierEntry, "LON"),
FreeCancellationUntil = GetValue(supplierEntry, "CANCELLATION_POLICY_FREE_CANCELLATION_UNTIL"),
Type = GetValue(supplierEntry, "CANCELLATION_POLICY_TYPE"),
NetRate = GetValue(supplierEntry, "PRICE_NET_RATE"),
FinalRate = GetValue(supplierEntry, "PRICE_FINAL_RATE"),
Currency = GetValue(supplierEntry, "PRICE_CURRENCY")
};
var rooms = supplierEntry.SelectTokens("properties[*].rooms[*]").Select(room => new RoomDto
{
RoomId = GetValue(room, "ROOM_ID"),
NoOfAdults = GetValue(room, "NO_OF_ADULTS"),
Price = new RoomPriceDto
{
NetPrice = GetValue(room, "ROOM_PRICE_NET_PRICE"),
GrossPrice = GetValue(room, "ROOM_PRICE_GROSS_PRICE"),
TotalPrice = GetValue(room, "ROOM_PRICE_TOTAL_PRICE")
},
Policies = new RoomPoliciesDto
{
Cancellation = new RoomCancellationDto
{
FreeCancellationUntil = GetValue(room, "ROOM_FREE_CANCELLATION_UNTIL"),
Type = GetValue(room, "ROOM_TYPE"),
PaymentTimings = GetValue(room, "ROOM_PAYMENT_TIMINGS")
}
}
}).ToList();
var transformedResponse = new ApartmentSearchResponseDTO
{
Results = new List
{
new ApartmentResultDTO
{
PropertyId = apartmentDetails.PropertyId,
Name = apartmentDetails.Name,
Address = apartmentDetails.Address,
Location = new LocationDto
{
Lat = apartmentDetails.Lat,
Lon = apartmentDetails.Lon
},
StarRating = apartmentDetails.StarRating,
Amenities = apartmentDetails.Amenities?.Distinct().ToList(),
Images = apartmentDetails.Images,
CancellationPolicy = new CancellationPolicyDto
{
FreeCancellationUntil = apartmentDetails.FreeCancellationUntil,
Type = apartmentDetails.Type
},
Price = new PriceDto
{
NetRate = apartmentDetails.NetRate,
FinalRate = apartmentDetails.FinalRate,
Currency = apartmentDetails.Currency
},
Rooms = rooms
}
},
Meta = null
};
return transformedResponse;
}
private T GetValue(JToken source, string placeholder)
{
var paths = GetPaths(placeholder);
foreach (var path in paths)
{
try
{
if (string.IsNullOrEmpty(path))
continue;
var tokens = source.SelectTokens(path).ToList();
if (tokens.Count == 1)
{
var token = tokens.First();
if (typeof(T) == typeof(List) && token.Type == JTokenType.Array)
{
return token.ToObject();
}
return token.Value();
}
else if (tokens.Count > 1)
{
if (typeof(T) == typeof(List))
{
var list = tokens.Select(t => t.ToString()).ToList();
return (T)(object)list;
}
}
}
catch (Exception)
{
continue;
}
}
return default;
}
private List GetPaths(string placeholder)
{
if (!_responseMappings.ContainsKey(placeholder))
{
return new List();
}
JToken pathsToken = _responseMappings[placeholder];
if (pathsToken.Type == JTokenType.Array)
{
return pathsToken.ToObject();
}
else if (pathsToken.Type == JTokenType.String)
{
return new List { pathsToken.ToString() };
}
return new List();
}
}
< /code>
Output:
[
{
"Results": [
{
"PropertyId": 12157,
"Name": "Medhufushi Island Resort",
"Address": null,
"Location": {
"Lat": 0.0,
"Lon": 0.0
},
"StarRating": 0,
"Amenities": [
"Breakfast",
"Dinner included",
"Lunch included",
"Welcome drink",
"Express check-in",
"Free WiFi",
"Drinking water",
"Free fitness center access"
],
"Images": null,
"CancellationPolicy": {
"FreeCancellationUntil": "12/16/2022 00:00:00",
"Type": "7D100P_100P"
},
"Price": {
"NetRate": 648.2,
"FinalRate": 798.58,
"Currency": "USD"
},
"SupplierDetails": null,
"Rooms": [
{
"RoomId": null,
"NoOfAdults": 0,
"Price": {
"NetPrice": 0.0,
"GrossPrice": 0.0,
"TotalPrice": 0.0
},
"Policies": {
"Cancellation": {
"FreeCancellationUntil": null,
"Type": null,
"PaymentTimings": null
}
}
},
{
"RoomId": null,
"NoOfAdults": 0,
"Price": {
"NetPrice": 0.0,
"GrossPrice": 0.0,
"TotalPrice": 0.0
},
"Policies": {
"Cancellation": {
"FreeCancellationUntil": null,
"Type": null,
"PaymentTimings": null
}
}
}
]
}
],
"Meta": null
}
]
Подробнее здесь: https://stackoverflow.com/questions/795 ... one-format
Преобразование нескольких форматов тела ответа в один формат ⇐ C#
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Обработка нескольких форматов: преобразование в дату и время (ММ:ДД:ГГГГ).
Гость » » в форуме Python - 0 Ответы
- 13 Просмотры
-
Последнее сообщение Гость
-