CreatedAtAction возвращает 500 в случае успеха

Обзор
 – проект Blazor Server с использованием REST API.
-HttpClient вызывает мой API, используя PostJsonAsync<>
-Db успешно обновляется и возвращает ожидаемый JSON
-API-контроллер Try/Catch не генерирует исключение, выполняет return CreatedAtAction()
-Вывод показывает, что API возвращает 500: Internal Server Ошибка
. При выполнении POST с использованием Swagger выполняется та же строка и возвращается 201

Я в недоумении, что происходит не так. Я занимаюсь программированием только с июля, так что я надеюсь, что просто недостаток опыта не позволяет мне увидеть очевидную проблему в моем коде. Это оскорбительный метод:

        public async Task<ActionResult<PlayerCharacter>> CreatePlayerCharacter(PlayerCharacter playerCharacter)
        {

            try
            {
                if (playerCharacter != null)
                {
                    var newPlayerCharacter = await _playerCharacterRepository.AddPlayerCharacter(playerCharacter);

                    //This is the last line of code to execute before the web app crashes with Status Code 500. Executes fine and returns 201 from Swagger.
                    return CreatedAtAction(nameof(GetPlayerCharacter), new { id = newPlayerCharacter.Id }, newPlayerCharacter);
                }

                return BadRequest();
            }
            catch (Exception e)
            {
                //This break point is not reached
                Console.WriteLine(e.StackTrace);
                return StatusCode(StatusCodes.Status500InternalServerError, "Error posting data to the database.");
            }
        }

Репозиторий GitHub


person Trevor    schedule 24.01.2021    source источник
comment
Полностью удалите try/catch (поскольку в ASP.NET Core для этого есть встроенная обработка исключений), а затем просмотрите журналы вашего сервера, чтобы узнать, что происходит. Сообщение об исключении должно дать вам хорошую идею.   -  person poke    schedule 24.01.2021
comment
Это приятно знать, спасибо! Я удалил try/catch и обнаружил, что то же самое сообщение отображается в моей трассировке стека.   -  person Trevor    schedule 24.01.2021
comment
Однако вы смотрите на трассировку стека потребителя; он получает только ошибку 500. Проверьте журналы вашего сервера, чтобы узнать, что вызвало ошибку 500.   -  person poke    schedule 24.01.2021
comment
Боюсь, здесь проявляется мой недостаток опыта... Я не знаю, как это сделать. Я подключил SQL Server Management Studio к своему LocalDb и вижу там базу данных. Я также нашел LDF для db. Интернет, похоже, считает, что это понимание требует довольно глубокого понимания T-SQL, которого у меня пока нет. Можете ли вы порекомендовать ресурс, который поможет мне найти эти журналы?   -  person Trevor    schedule 24.01.2021
comment
Вам нужно будет просмотреть журналы ASP.NET Core. Если вы запускаете свое приложение из Visual Studio с помощью IIS Express, проверьте панель «Вывод» и выберите «ASP.NET Core» в раскрывающемся списке. В противном случае, если вы запускаете приложение как консольное приложение (или из другого места, кроме VS), тогда у вас должно быть где-то открыто окно консоли, которое должно содержать все журналы.   -  person poke    schedule 24.01.2021
comment
Ах! Я узнал кое-что новое! Похоже, что исключение: System.Text.Json.JsonException: Обнаружен возможный объектный цикл... [и др.]. Похоже, мне нужно добавить обработчик эталонного цикла. Эта информация выглядит так, как будто она устарела и не совсем работает. Мне нужно выполнить поручение, но я изучу это позже. Большое вам спасибо за вашу помощь! entityframeworkcore.com/knowledge-base/59199593/   -  person Trevor    schedule 24.01.2021


Ответы (1)


Основная причина проблемы еще не до конца понятна, но я знаю, как я ее исправил.

После того как poke научил меня просматривать журналы ASP.NET Core, я обнаружил следующее исключение:
System.Text.Json.JsonException: обнаружен возможный объектный цикл. Это может быть связано с циклом или с тем, что глубина объекта больше максимально допустимой глубины 32. Рассмотрите возможность использования ReferenceHandler.Preserve в JsonSerializerOptions для поддержки циклов.

Поиски привели меня к нескольким ресурсам:

Решение может заключаться в том, что я должен реорганизовать свой код для использования DTO (что-то, что мне нужно будет прочитать, потому что я еще этого не понимаю). А пока что лейкопластырь, который позволит мне продолжить, таков:

  1. Установите пакет NuGet Microsoft.AspNetCore.Mvc.NewtonsoftJson
  2. В Statup.cs в ConfigureServices добавить
services.AddControllers().AddNewtonsoftJson(options =>
                options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore);

Спасибо всем, кто помог мне обдумать это. Я очень ценю вашу помощь!

person Trevor    schedule 24.01.2021
comment
Ошибка, вероятно, возникает из-за того, что вы возвращаете newPlayerCharacter типа PlayerCharacter, который имеет ссылки на такие вещи, как PlayerAttribute, которые снова ссылаются на PlayerCharacter. При сериализации этого как JSON сериализатор будет просто следовать этим путям объекта до бесконечности (пока не сломается). – Лучше всего определить настраиваемый объект передачи данных (DTO), который вы возвращаете и который хорошо сериализуем. Таким образом, вы также упрощаете сокрытие определенных деталей реализации, которые клиент не должен знать или не должен знать. - person poke; 25.01.2021