11
votes

In my WebAPI class, an ApiController, I make a call such as:

string myCustomMessage = .....;

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

When I call using AngularJS $resource service, I do get 401 in the status field the response, in the catch block of the promise. The 401 matches HttpStatusCode.Unauthorized, so all's well.

The problem, however, is that the data field of the response is empty (null). I don't get the myCustomMessage returned.

Now, if rather than throwing a HttpResponseException exception, I just throw a regular Exception with a message, that message does make it sway back to Angular.

I need to be able to do both: return a custom message from the server, as well as have the returned status code be whatever I want, in this case 401.

Anyone know how to make that work?

[edit] Solution:

 throw new HttpResponseException(
     Request.CreateErrorResponse(HttpStatusCode.Unauthorized, myCustomMessage));
2
What happens if you use plain $http?Karolis Juodelė
Karolis, I am okay with using plain $http. I would do that if we've determined that $resource cannot be used to solve this problem. Has that been confirmed?Daisha Lynn

2 Answers

11
votes

Try returning HttpResponseMessage like this.

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

This should produce an HTTP response message like this.

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"}
0
votes

I use a response interceptor for that. A response interceptor is pretty much a "filter" where all responses pass through and I can ask about there status code and perform logic.

Something like this:

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');
});

About your custom message, you can add it in a http header. In my case, when I get a 401, I add a location header with a url and redirect to it.