【问题标题】:AngularJS - $http error callback not working even though error response returned from the Web APIAngularJS - 即使从 Web API 返回错误响应,$http 错误回调也不起作用
【发布时间】:2013-11-07 23:29:19
【问题描述】:

我正在从服务器调用一个方法,该方法返回一个错误响应,例如(400 和 500 个错误),但我的 AngularJS 错误回调没有被调用,并且即使我的状态代码包含 400 或 500,也总是调用成功回调。有人可以告诉我我做错了什么吗?请参阅下面的 Angular 和 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
}

【问题讨论】:

  • 你能在浏览器网络选项卡中查看响应状态吗
  • 您的 JavaScript 正在调用 GET,但您发布了 PUT 的代码。使用浏览器调试工具或 Fiddler 看看发生了什么。
  • 抱歉打错了。此外,这就是我得到的响应:HTTP/1.1 400 Bad Request Cache-Control: no-cache Pragma: no-cache Expires: -1 Server: Microsoft-IIS/8.0 X-AspNet-Version: 4.0.30319 X-SourceFiles: =?UTF-8?B?RDpcU2hhblxDb25zdHJ1Y3Rpb25XZWJBcGlcQ29uc3RydWN0aW9uV2ViQXBpXGFwaVxzdXBwbGllcg==?= X-Powered-By: ASP.NET Date: Tue, 29 Oct 29 21:21:18 GMT Content-Length:
  • 您使用的是哪个 AngularJS 版本? AngularJS 1.2 版存在问题。[*|rc] 版本。您可以升级到最新的 stable(1.2.9) 版本,它会正常工作。

标签: angularjs asp.net-web-api


【解决方案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 中的第二个函数,如果没有其他错误处理需要完成,从而节省代码和带宽。

【讨论】:

    【解决方案2】:

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

    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】:

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

      当调用拦截器的 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 中拒绝,它是行不通的,你需要返回拒绝,这样下面的元素就会得到通知。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-09-07
        • 1970-01-01
        • 2020-11-23
        • 2013-10-21
        • 2014-01-09
        • 2022-06-10
        相关资源
        最近更新 更多