ReadFromJsonAsync возвращает свойства объекта с нулевыми значениями

#asp.net-core #blazor #webassembly

#c# #asp.net-core #blazor #webassembly

Вопрос:

У меня есть приложение для веб-сборки Blazor (ASP.Net Размещенное на ядре, прогрессивное веб-приложение) со следующей логикой:

Клиент:

 protected override async Task OnInitializedAsync() {
    string token = await _loginService.GetToken();

    _http.DefaultRequestHeaders.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", token);

    var result = await _http.PostAsJsonAsync("api/api/getcalllogs", userCallsRequestFilters);

    if (result.IsSuccessStatusCode) {
        var morUserCallLogs = await result.Content.ReadFromJsonAsync < MorUserCallLogsResponse > ();

        await js.InvokeAsync < object > ("TestDataTablesAdd", "#example");
    } else {
        morUserCallLogs = new MorUserCallLogsResponse();
    }
}
  

Сервер: (на стороне сервера API У меня есть следующий код, который работает так, как ожидалось:)

 [Authorize]
[ApiController]
[Route("api/[controller]")]
public class MorApiController : ControllerBase
...

[HttpPost("getcalllogs")]
public async Task<MorUserCallLogsResponse> GetCallLogs ([FromBody] MorUserCallsRequestFilters filters)
{
...
return resu<
  

Серверный контроллер API заполняет модель нормально, и когда я проверяю, я вижу следующую привязку (* некоторые значения были отключены для безопасности)
введите описание изображения здесь

Модель: (Моя модель MorUserCallLogsResponse выглядит следующим образом:)

 namespace MyNumberV2.Model
{
    public class MorUserCallLogsResponse
    {
        public MorUserCallLogsResponse()
        { 
            Calls = new List<MorCall>();
        }
        public string Error { get; set; }
        public bool IsSuccessfull { get; set; }
        public string userid;
        public string username;
        ...
        ...
        public List<MorCall> Calls { get; set; }
        public class MorCall
        {
            public string calldate2;
            public string timezone;
            ...
            ...
        }
    }
}
  

Возвращаюсь к blazor и когда я пытаюсь прочитать этот возвращенный объект в следующей строке:

 var morUserCallLogs = await result.Content.ReadFromJsonAsync<MorUserCallLogsResponse>();
  

Моя восстановленная модель выглядит следующим образом:
введите описание изображения здесь

Как вы можете видеть, моя извлеченная модель содержит все свойства с 140 вложенными моделями объектов вызовов, однако все свойства равны нулю…

Комментарии:

1. Классическая проблема с сериализацией / десериализацией JSON camelCase / PascalCase

2. @aguafrommars Чувак, огромное СПАСИБО, мне пришлось настроить параметры для того, чтобы json не учитывал регистр, и передать ему метод ReadFromJsonAsync var options = new JsonSerializerOptions() { Converters = { new JsonStringEnumConverter() }, PropertyNameCaseInsensitive = true }; Я также добавил преобразователи для перечислений, исходя из моих потребностей.

3. Возможно, было бы лучше использовать JsonSerializerDefaults.Web в качестве отправной точки: var options = new JsonSerializerOptions(JsonSerializerDefaults.Web); options.Converters.Add(new JsonStringEnumConverter());

Ответ №1:

Я забыл добавить get; set; для ВСЕХ свойств моей модели…

{ получить; установить; }

   public string Error { get; set; }
  public bool IsSuccessfull { get; set; }
  public string userid { get; set; }
  public string username { get; set; }
  .....
  

Комментарии:

1. Хорошо, поля не сериализуются, это делают свойства.

2. в VS есть фрагмент кода для создания автоматических свойств. Введите prop и дважды нажмите tab. Я использую это для создания новых свойств.

3. Кроме того, установщики должны быть общедоступными. Одна из причин, по которой я все еще использую Newtonsoft

4. Мои свойства являются общедоступными с помощью { get; set; }, и мой объект по-прежнему имеет значения по умолчанию, так что это не решило проблему для меня.

Ответ №2:

Мне пришлось использовать следующее из аннотации свойства using System.Text.Json.Serialization

  [JsonPropertyName("access_token")]
 public string AccessToken { get; set; }
  

Ответ №3:

Мой был исправлен путем передачи в ReadFromJsonAsync метод параметра options, который сделал бы json нечувствительным к регистру свойств в json, поэтому в вашем случае это выглядело бы так:

 var options = new JsonSerializerOptions
{
    PropertyNameCaseInsensitive = true
};
var result = await result.Content.ReadFromJsonAsync<MorUserCallLogsResponse>(options);
  

Ответ №4:

"api/api/getcalllogs" не соответствует [Route("api/[controller]")] и [HttpPost("getcalllogs")]

Когда я прочитал это, URL-адрес должен быть "api/MorApi/getcalllogs"

Но опять же, это должно привести к 404 или 400

Комментарии:

1. Исправьте, это было изменено по ошибке, но только в stackoverflow, фактический код гласит: var result = await _http. PostAsJsonAsync(«api/morapi/getcalllogs», userCallsRequestFilters);