#c# #asp.net-core #asp.net-core-3.1 #json-deserialization
#c# #asp.net-core #asp.net-core-3.1 #json-десериализация
Вопрос:
В моем веб-приложении .Net Core 3.1 у меня есть класс, разделяемый серверной частью и интерфейсом, который выглядит следующим образом
public class Order
{
[Key]
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public DateTime OrderTime { get; set; }
public int UserId { get; set; }
public int Vat { get; set; }
[NotMapped]
public Dictionary<string, int> Products { get; set; }
public int Discount { get; set; }
public float ShippingPrice { get; set; }
public bool Shipped { get; set; }
public bool Cancelled { get; set; }
public string CancelReason { get; set; }
public Order()
{
}
}
И в интерфейсе я использую HttpClient для получения списка заказов из REST API.
Json, который получает HttpClient, выглядит следующим образом:
[
{
"id": 1,
"orderTime": "2021-01-28T14:55:03.077",
"userId": 0,
"vat": 0,
"products": null,
"discount": 0,
"shippingPrice": 0,
"shipped": true,
"cancelled": true,
"cancelReason": "string"
},
{
"id": 2,
"orderTime": "2021-01-28T14:55:03.077",
"userId": 2,
"vat": 0,
"products": null,
"discount": 10,
"shippingPrice": 0,
"shipped": false,
"cancelled": false,
"cancelReason": null
}
]
И для десериализации я использую JsonSerializer:
var returnOrders = await JsonSerializer.DeserializeAsync<List<Order>>(await response.Content.ReadAsStreamAsync());
Из этого я получаю правильное количество объектов в списке, но все они имеют значения 0 или null и т.д.
Что я делаю не так?
Раньше я использовал ReadAsAsync(), который работал нормально, но устарел.Net core 3
await response.Content.ReadAsAsync<List<Object>>();
Комментарии:
1. Вы проверили запрос, который вы запускаете, имеет ли
Order.Products
значение? Я имею в виду, соответствует ли ваш запросInclude
отображенным объектам там? Верны ли ваши данные, я имею в виду, должны ли там быть данные?2. Продукты в базе данных равны нулю, все в порядке. Но, например, идентификатор для всех объектов равен 0, чего нет в Json
3. Поэтому, если вам нужно другое значение по умолчанию
Order.Products
, отличное от null, когда в базе данных нет данных, я бы инициировалOrder.Products
field int он конструктор. В результате это будет список с нулевым элементом. Это то, что вы ищете?4. Я думаю, вы, возможно, неправильно поняли мою проблему здесь. Объект, который я получаю в результате десериализации, отличается от объекта в Json и Db. И это относится к объекту или порядку, а не к конкретному порядку. Продукты
5. Вам нужно убедиться, что написание ваших свойств такое же, как в файле json. Если вы хотите использовать другое написание, вам нужно использовать атрибуты, чтобы указать десериализатору json, какое свойство является полем в json
Ответ №1:
По умолчанию JsonSerializer ищет свойства в json с тем же именем, что и у определенного в вашем классе. В вашем случае вы используете соглашение об именовании camelCase, поэтому вам нужно указать его следующим образом:
var options = new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
var returnOrders = await JsonSerializer.DeserializeAsync<List<Order>>(await response.Content.ReadAsStreamAsync(), options);
Ответ №2:
Это может произойти из-за соглашений о десериализации JSON, используемых различными десериализаторами. Например, некоторое время имеет значение случай ключей JSON.
Попробуйте использовать десериализатор NewtonsoftJSON вместо используемого по умолчанию. Он будет анализировать JSON без проверки регистра.
string json = @"{
'Email': 'james@example.com',
'Active': true,
'CreatedDate': '2013-01-20T00:00:00Z',
'Roles': [ 'User', 'Admin' ]
}";
Account account = JsonConvert.DeserializeObject<Account>(json);
Console.WriteLine(account.Email);
Комментарии:
1. Ну, у меня один и тот же класс для интерфейса и серверной части, и оба они используют один и тот же сериализатор в System.Text.Json. Если я использую NewtonsoftJson, который используется Microsoft. AspNet. WebAPI.Client работает нормально. Я не вижу причин, по которым он не десериализовался бы с помощью System.Text. Json, когда он был сериализован с ним.
2. Я понял вашу точку зрения, и вы совершенно правы. Однако суть, которую я пытаюсь подчеркнуть, заключается в том, как другой десериализатор обрабатывает синтаксический анализ JSON. Я столкнулся с такой же, хотя и похожей проблемой год назад, и решил ее, переключив мой анализатор JSON. @Snackerino