Как мне вернуть результат из класса службы/варианта использования? ⇐ C#
-
Гость
Как мне вернуть результат из класса службы/варианта использования?
При разработке REST API с использованием C# у меня возникла проблема: если служба, используемая контроллером, возвращает ошибку, но ошибка зависит от бизнес-правил, как и где мне следует определить, какой код состояния следует возвращать в ответе HTTP?
Я имею в виду, должна ли это быть обязанностью службы или контролер должен определять, какой код состояния возвращать на основе результата службы?
Сегодня моя команда заставляет службы возвращать код состояния и сообщение, а также полезную нагрузку через общий объект-оболочку из класса под названием Response. Поэтому, когда мы хотим вернуть, например, список пользователей, сервис делает что-то похожее на
if (!users?.Any() ?? true) вернуть новый ответ() { Сообщение = "Нет пользователей.", Статус = HttpStatusCodes.Status204NoContent } вернуть новый ответ() { Сообщение = "Пользователи извлечены успешно!", Статус = HttpStatusCodes.Status200OK, Данные = пользователи } Однако мне этот способ кажется не совсем удачным, хотя он и работает, потому что странно вызывать один метод из ServiceA в ServiceB, учитывая тот факт, что код состояния HTTP иногда объединяется без необходимости.
Одной из альтернатив для этого является возврат некоторого объекта Result из Службы в Контроллер, но выполнение некоторой обработки данных в промежуточном программном обеспечении, преобразующее объект Result в эффективный объект Response, содержащий код состояния.
Это может быть что-то вроде этого:
// Объект результата, возвращаемый службами публичный класс Result { общественная строка Сообщение {получить; } общественная причина ResultReason {get; } общественные данные T {получить; набор; } } публичное перечисление ResultReason { BusinessRuleViolation, ItemNotFound, Успех, ИнвалидПараметр } // Объект ответа, возвращаемый промежуточным программным обеспечением как тело ответа HTTP открытый класс Response { общественная строка Сообщение {получить; } общественный ИНТ StatusCode {получить; } общественные данные T {получить; набор; } } общедоступный статический класс ResultMapper { общедоступный статический Response ToResponse(этот результат Result) { вернуть новый ответ() { Данные = Результат.Данные, Сообщение = результат.Сообщение, StatusCode = result.Reason == ResultReason.BusinessRuleViolation ? 422 : result.Reason == ResultReason.ItemNotFound ? 204 : result.Reason == ResultReason.Success ? 200 : result.Reason == ResultReason.InvalidParameter ? 400 } } } Желательно, я избегаю использования исключений из соображений производительности.
Примечание. Приведенный выше пример не обязательно работает, я написал его только в демонстрационных целях.
При разработке REST API с использованием C# у меня возникла проблема: если служба, используемая контроллером, возвращает ошибку, но ошибка зависит от бизнес-правил, как и где мне следует определить, какой код состояния следует возвращать в ответе HTTP?
Я имею в виду, должна ли это быть обязанностью службы или контролер должен определять, какой код состояния возвращать на основе результата службы?
Сегодня моя команда заставляет службы возвращать код состояния и сообщение, а также полезную нагрузку через общий объект-оболочку из класса под названием Response. Поэтому, когда мы хотим вернуть, например, список пользователей, сервис делает что-то похожее на
if (!users?.Any() ?? true) вернуть новый ответ() { Сообщение = "Нет пользователей.", Статус = HttpStatusCodes.Status204NoContent } вернуть новый ответ() { Сообщение = "Пользователи извлечены успешно!", Статус = HttpStatusCodes.Status200OK, Данные = пользователи } Однако мне этот способ кажется не совсем удачным, хотя он и работает, потому что странно вызывать один метод из ServiceA в ServiceB, учитывая тот факт, что код состояния HTTP иногда объединяется без необходимости.
Одной из альтернатив для этого является возврат некоторого объекта Result из Службы в Контроллер, но выполнение некоторой обработки данных в промежуточном программном обеспечении, преобразующее объект Result в эффективный объект Response, содержащий код состояния.
Это может быть что-то вроде этого:
// Объект результата, возвращаемый службами публичный класс Result { общественная строка Сообщение {получить; } общественная причина ResultReason {get; } общественные данные T {получить; набор; } } публичное перечисление ResultReason { BusinessRuleViolation, ItemNotFound, Успех, ИнвалидПараметр } // Объект ответа, возвращаемый промежуточным программным обеспечением как тело ответа HTTP открытый класс Response { общественная строка Сообщение {получить; } общественный ИНТ StatusCode {получить; } общественные данные T {получить; набор; } } общедоступный статический класс ResultMapper { общедоступный статический Response ToResponse(этот результат Result) { вернуть новый ответ() { Данные = Результат.Данные, Сообщение = результат.Сообщение, StatusCode = result.Reason == ResultReason.BusinessRuleViolation ? 422 : result.Reason == ResultReason.ItemNotFound ? 204 : result.Reason == ResultReason.Success ? 200 : result.Reason == ResultReason.InvalidParameter ? 400 } } } Желательно, я избегаю использования исключений из соображений производительности.
Примечание. Приведенный выше пример не обязательно работает, я написал его только в демонстрационных целях.
Мобильная версия