Подтвердить что ты не робот

Лучшая практика: способы обработки ошибок и исключений в контроллерах web-api?

Я работаю над проектом и в значительной степени полагаюсь на веб-api для всех своих операций на стороне клиента, будь то обновление учетной записи, новые детали, изменение, все было сделано с помощью ASP.NET Web Api и Backbone.js

Текущая сцена:

В текущей схеме вещей я возвращаю логическое значение из своих веб-контроллеров api, чтобы указать, была ли операция успешной или нет.

Пример:

[ActionName("UpdateAccountDetails")]
public bool PostAccountDetails(SomeModel model)
{
    bool updateStatus = _customService.UpdateAccountDetails(model);
    return updateStatus;
}

поэтому после выполнения ajax-вызова этого действия я проверяю ответ на истинные/ложные и выводит сообщение об ошибке или сообщения об успешном завершении.

Проблема:

Теперь случилось то, что я начал получать исключения в своем действии, и действие продолжало возвращать false, и было показано сообщение об ошибке. Но я не смог найти почему?

Итак, мне было интересно, существует ли стандартная структура ответа api, которую каждый из них следует?

Я изначально придумал эту идею, чтобы каждое действие веб-api возвращало этот класс

public class OperationStatus
{
    public bool Result { get; set; } // true/false
    public string Status { get; set; } // success/failure/warning
    public List<string> WarningMessages { get; set; }
    public List<string> ErrorMessages { get; set; }
    public string OtherDetails { get; set; }
}

Это изменение будет серьезным изменением, и это будет время и ресурсы, поэтому я подумал, что лучше иметь второе/третье/четвертое мнение по этому поводу.

Подумайте об этом.

Обновление:

С помощью небольшой помощи от Mark Jones я придумал этот

[ActionName("UpdateAccountDetails")]
public HttpResponseMessage PostAccountDetails(SomeModel model)
{
    bool updateStatus;
    string errorMessage;
    try{
        updateStatus = _customService.UpdateAccountDetails(model);
        if(updateStatus)
        {
            return Request.CreateResponse(HttpStatusCode.OK);
        }
        return Request.CreateResponse(HttpStatusCode.InternalServerError);
    }
    catch(Exception exception)
    {
        errorMessage = exception.Message;
        return Request.CreateResponse(HttpStatusCode.InternalServerError, errorMessage);
    }

    return updateStatus;
}

Любая мысль об этом?

4b9b3361

Ответ 1

Вам следует избегать использования try/catch в действии контроллера.

Существует множество способов решения вашей проблемы. Простейшим и самым чистым решением, вероятно, будет использование ActionFilter для обработки исключений, что-то вроде строк:

public class ExceptionAttribute : ExceptionFilterAttribute
{
    public override void OnException(HttpActionExecutedContext context)
    {
        Debug.WriteLine(context.Exception);

        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
        {
            Content = new StringContent("An error occurred!"),
            ReasonPhrase = "Deadly Exception"
        });
    }
}

Затем вы можете просто украсить свое действие [ExceptionAttribute]. Разумеется, вы можете расширить это поведение по-разному для разных типов исключений - бизнес-исключения, исключения данных, исключения IO и т.д., А также вернуть другие коды состояния и обратную связь на основе этого.

Я рекомендую вам прочитать отличную статью Фредрика Нормена - "Обработка исключений веб-API ASP.NET" http://weblogs.asp.net/fredriknormen/archive/2012/06/11/asp-net-web-api-exception-handling.aspx.

Он предоставляет большой обзор методов обработки исключений для веб-API.

Ответ 2

Вместо того, чтобы возвращать HttpResponseMessage, я бы оставил API одинаковым и просто выбросил исключение HttpResponseException, когда вы поймаете исключение. Что-то вроде этого:

throw new HttpResponseException(
    new HttpResponseMessage(HttpStatusCode.InternalServerError) 
       { ReasonPhrase = errorMessage });

Таким образом, вы не изменяете определение своего API и не будете работать с вашими действиями GET, где вы возвращаете некоторый объект, который должен быть сериализован. Если вы используете JQuery ajax-метод для отправки запроса, ваш обработчик error поймает это, и вы сможете получить текстовое сообщение в параметре errorThrown и обработать его соответствующим образом.