Возврат соответствующих сообщений вызывающему клиенту - PullRequest
0 голосов
/ 07 июня 2019

Это очень похоже, но мой вопрос другой: Возврат содержимого с помощью IHttpActionResult для ответа не в порядке

Учитывая, что вопрос другой, я прошу более краткий ответ, если он существует.

Моя архитектура следующая:

  1. вызов Javascript / jQuery для внутреннего контроллера
  2. Внутренний контроллер вызывает службу WebAPI
  3. Сервис WebAPI запрашивает БД (и т. Д.) И возвращает данные

У меня есть следующий упрощенный код (веб-API) ...

Пример 1: ошибка возврата, если идентификатор продукта не существует:

public IHttpActionResult GetProduct(int id)
{
    var product = products.FirstOrDefault((p) => p.Id == id);
    if (product == null)
    {
        return NotFound();
    }
    return Ok(product);
}

Пример 2 возвращает пустые данные, если идентификатор продукта не существует:

public IHttpActionResult GetProduct(int id)
{
    var product = products.FirstOrDefault((p) => p.Id == id);
    return Ok(product);
}

JS на стороне клиента:

$.getJSON("example.json", function() {
  alert("success");
})
.done(function() { alert('Product retrieved'); })
.fail(function() { alert('Product doesn't exist. '); })
.always(function() { ... });

Я много раз читал, что использование исключений для управления потоком является плохой практикой, что, в сущности, произойдет, если я использую NotFound(), поскольку он попадет в функцию .fail, предполагая, что произошла ошибка (которая не было)

В другом случае, когда комментарий должен быть одобрен кем-то, кроме человека, вставившего комментарий:

public IHttpActionResult ApproveComment(int rowId, string userName)
{
    try {
        return Ok(BusinessLogicLayer.ApproveComment(rowId, userName));
    }
    catch(Exception ex)
    { 
        // elmah.logerr...
        throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.InternalServerError, ex.InnerException == null ? ex.Message : ex.InnerException.Message));
    }
}

BusinessLogicLayer:
public string ApproveComment(int rowId, string userName)
{
    if (userName == _repository.GetInsertedCommentUserName()) {
        return "You cannot approve your own comment.";
    }
    if(_repository.ApproveComment(rowId, userName)){
        return "Comment approved";
    }
}

ИЛИ

public string ApproveComment(int rowId, string userName)
{
    if (userName == _repository.GetInsertedCommentUserName()) {
        throw new Exception("You cannot approve your own comment.");
    }
    if(_repository.ApproveComment(rowId, userName)){
        return "Comment approved";
    }
}

Что такое чистый и элегантный способ вернуть соответствующее сообщение пользователю без использования исключений?

Или я ошибаюсь, это «исключительные» обстоятельства с точки зрения пользователей? IE. "Я ожидаю, что продукт будет возвращен, когда я передам этот идентификатор, но, увы, его не существует!" С точки зрения разработчиков / тестировщиков, я не думаю, что это был бы исключительный случай, но с точки зрения конечного пользователя - возможно.

Ответы [ 2 ]

2 голосов
/ 07 июня 2019

Вы задаете два разных вопроса.Итак, давайте ответим на них один за другим.

Проблема «не найден»

В первом случае клиент пытается получить доступ к несуществующему продукту.Соответствующий код состояния для возврата с сервера 404, не найден.Для клиента это на самом деле исключительный случай, потому что он, вероятно, пытается получить доступ к существующему ресурсу.В части «fail» вашего javascript на стороне клиента вы можете проверить причину сбоя запроса (диапазон 4xx = ошибка на стороне клиента, диапазон 5xx = ошибка на стороне сервера) и показать соответствующие сообщения пользователю.

Проблема с утверждением

Для решения проблемы вы возвращаете неиспользуемые коды состояния.Вы должны проверить, существует ли ресурс, который клиент пытается утвердить, прежде чем утверждать.Если ресурс не существует, это ошибка на стороне клиента, и вы должны вернуть 404, не найдено.Если каким-либо образом обновление ресурса уровнем бизнес-логики все еще не удается, и это проблема сервера, вы должны вернуть 500, внутренняя ошибка сервера.Для любой ситуации, когда клиенту не удалось выполнить обновление, верните код состояния в диапазоне 4xx.(например, 403, неавторизовано, если клиенту не разрешено утверждать свои собственные комментарии)

1 голос
/ 07 июня 2019

Утверждение ваших собственных комментариев - Это похоже на недопустимую операцию .Для этого есть исключение.

И тогда это неверный запрос от клиента.Для этого есть код состояния ответа.

Нет ничего плохого в том, что в вашем коде есть исключения, если вы обрабатываете их последовательно.И нет ничего плохого в том, чтобы выдавать коды статуса 4xx, если вы корректно обрабатываете их на стороне клиента. Это запрос, который должен быть запрещен клиенту, поэтому он должен завершиться неудачей , не так ли?

Ваш второй пример не эквивалентен первому.Во втором примере вы определенно не добьетесь чего-либо.Это Плохой запрос .

Первый пример, ну, вы пытаетесь достичь что-то, что не запрещено по умолчанию - получение записи с заданным идентификатором.И случается так, что эта запись не существует.Это тот случай, когда ваш предмет был не найден .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...