AngularJS - 即使从Web API返回错误响应,$ http错误回调也无法正常工作

时间:2013-10-29 00:28:37

标签: angularjs asp.net-web-api

我正在从服务器调用一个方法,它返回一个错误响应,如(400& 500错误),但我的AngularJS错误回调没有被调用,即使我的状态代码包含400或500,我的调用成功回调总是被调用。谁能告诉我我做错了什么?请看角度& WebAPI代码如下:

AngularJS代码:

$http.get("/api/employee")
    .success(function (data, status, headers, config) {
        console.log(data);
        return data;
    }).error(function (data, status, headers, config) {
        alert("error");
        return status;
});

Web API代码:

public HttpResponseMessage Get(EmployeeModel employee)
{
     if (!ModelState.IsValid)
     {
         return Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState);
     }
     //some other code
}

4 个答案:

答案 0 :(得分:16)

问题是有一个拦截器,它不能正确传播错误。

当调用拦截器的responseError时,它必须将异常传播到调用堆栈中,因此以下函数调用/回调将知道出现错误而不是成功的响应。



$httpProvider.interceptors.push(function ($q, $rootScope) {

        return {
            request: function (config) {
                //the same config / modified config / a new config needs to be returned.
                return config;
            },
            requestError: function (rejection) {
                return $q.reject(rejection);
            },
            response: function (response) {
                //the same response/modified/or a new one need to be returned.
                return response;
            },
            responseError: function (rejection) {
                return $q.reject(rejection);
            }
        };
    });




提到的Matthias是正确的,但它没有返回元素。因此,如果你只是拒绝在responseError中,它不起作用,你需要返回拒绝,以便通知以下元素。

答案 1 :(得分:6)

我遇到了同样的问题,我现在仍在自己解决这个问题,但我发现了一个可能的问题。

HTTP响应拦截器(通过添加到.error()数组注册)可能会阻止$httpProvider.interceptors回调执行。

我正在使用一个模块来添加拦截器,所以我删除了它并手动编写了这些东西。

答案 2 :(得分:2)

我创建了一个拦截器来捕获每个HTTP请求的延迟并面临同样的问题。解决方案非常简单。只需替换:返回响应; 返回$ q.reject(响应); 。例如:

SCM.service('httpService', function($q) {
    this.request = function(config) {
        if (angular.isObject(config)) {
            config.delay = new Date().getTime();
        }
        return config;
    };
    this.requestError = function(config) {
        if (angular.isObject(config)) {
            config.delay = new Date().getTime();
        }
        return $q.reject(config);
    };
    this.response = function(response) {
        if (angular.isObject(response.config)) {
            response.config.delay = new Date().getTime() - response.config.delay;
        }
        return response;
    };
    this.responseError = function(response) {
        if (angular.isObject(response.config)) {
            response.config.delay = new Date().getTime() - response.config.delay;
        }
        return $q.reject(response);
    };
});

SCM.config(function($httpProvider) {
    $httpProvider.interceptors.push('httpService');
});

答案 3 :(得分:1)

我从未对.success和.error选项感到好运,最终使用了.then用于所有内容并且还没有出现问题。我还应该指出,你不能从你想要做的承诺中返回价值。在输入promise之前,您必须使用var声明变量,或者在promise中分配新的$ scope变量。

因此,通过这些更改,您的代码将如下所示:

var employees = $http({method:'GET', url:'/api/employee');
employees.then(function(data){
    $scope.employeeData = data;
}, function(data){
    //do error handling here
});

此外,有一个集中的方法来处理错误有时可能会有所帮助,这可以使用httpInterceptor完成(详见此处:Handle HTTP 302 response from proxy in angularjs)。如果没有其他错误处理要做,这样做可以让你完全删除.then中的第二个函数,从而节省代码和带宽。