Как вернуть статус 401 из WebAPI в AngularJS, а также включить специальное сообщение?

В моем классе WebAPI, ApiController, я делаю вызов, например:

string myCustomMessage = .....;

throw new HttpResponseException(
    new HttpResponseMessage(HttpStatusCode.Unauthorized)
        { ReasonPhrase = myCustomMessage });

Когда я звоню с помощью услуги AngularJS $resource, я получаю 401 в поле статуса ответ в блоке catch обещания. 401 соответствует HttpStatusCode.Unauthorized, поэтому все хорошо.

Однако проблема заключается в том, что поле данных ответа пусто (null). Я не возвращаю myCustomMessage.

Теперь, вместо того, чтобы бросать исключение HttpResponseException, я просто бросаю регулярный Exception с сообщением, это сообщение действительно возвращает его к Angular.

Мне нужно иметь возможность сделать так: вернуть пользовательское сообщение с сервера, а также вернуть код состояния, который я хочу, в этом случае 401.

Кто-нибудь знает, как сделать эту работу?

[править] Решение:

 throw new HttpResponseException(
     Request.CreateErrorResponse(HttpStatusCode.Unauthorized, myCustomMessage));

Ответ 1

Попробуйте вернуть HttpResponseMessage, как это.

public HttpResponseMessage Get()
{
    return Request.CreateErrorResponse(
              HttpStatusCode.Unauthorized, "You are not authorized");
}

Это должно привести к сообщению HTTP-ответа, подобному этому.

HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/8.0
Date: Sat, 12 Apr 2014 07:12:54 GMT
Content-Length: 36

{"Message":"You are not authorized"}

Ответ 2

Я использую для этого ответный перехватчик. Ответчик-перехватчик в значительной степени является "фильтром", в котором проходят все ответы, и я могу спросить о нем код состояния и выполнить логику.

Что-то вроде этого:

myModule.factory('responseInterceptor', function ($q) {
    return {
        response: function (res) {
           switch(res.status){
             case 401:
                     // do what you want
           }
           return res;
        },
        responseError: function (res) {
            return $q.reject(res);
        }
    };
});

myModule.config(function ($httpProvider) {
    $httpProvider.interceptors.push('responseInterceptor');
});

О вашем пользовательском сообщении вы можете добавить его в заголовок http. В моем случае, когда я получаю 401, я добавляю заголовок местоположения с URL-адресом и перенаправляю его.