Angular $ http执行函数“success”而不是“error”

时间:2016-11-18 12:59:15

标签: angularjs asp.net-web-api oauth

我的Angular客户端调用web api函数,该函数检查用户是否通过密码和用户名授权。以下是该方法的相关开头:

        public override async Task GrantResourceOwnerCredentials(OAuthGrantResourceOwnerCredentialsContext context)
    {
        var allowedOrigin = context.OwinContext.Get<string>("as:clientAllowedOrigin");
        var userManager = context.OwinContext.Get<DividendsManagerUserManager>();

        if (allowedOrigin == null) allowedOrigin = "*";

        context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] { allowedOrigin });

        var user = await userManager.FindAsync(context.UserName, context.Password);
        if (user == null)
        {
            context.SetError("invalid_grant", "Der Benutzername oder das Passwort ist ungültig.");
            return;
        }

如您所见,如果提供的登录无效,我会使用context.SetError。这样做会返回此消息,如Fiddler:

中所示
HTTP/1.1 400 Bad Request

缓存控制:无缓存 Pragma:没有缓存 Content-Type:application / json; charset = UTF-8 到期:-1 服务器:Microsoft-IIS / 10.0 Access-Control-Allow-Origin:* X-Powered-By:ASP.NET 日期:2016年11月18日星期五12:49:10 GMT 内容长度:97

{“error”:“invalid_grant”,“error_description”:“Der Benutzername oder das Passwortistungültig。”}

对我来说很好看。但是在Angular中,api调用“成功”,因为执行了成功函数回调:

        var _login = function(loginData) {

            var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password + "&client_id=" + authSettings.clientId;

            var deferred = $q.defer();

            $http.post(serviceBase + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function(response) {

                localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName, refreshToken: response.refresh_token, useRefreshTokens: true });

                fillAuthData();

                deferred.resolve(response);

            }).error(function(err, status) {
                _logOut();
                deferred.reject(err);
            });

            return deferred.promise;
        };

任何人都知道错误是什么?

此致

的Torsten

P.S。:在成功函数中,我可以检查响应是否包含错误。但这感觉就像一个糟糕的黑客。

2 个答案:

答案 0 :(得分:1)

在保证链中,通过将值返回到拒绝处理程序,拒绝可以转换成功。这使得修复问题和重试操作成为可能。但它也可能导致与不需要的转换相关的错误。

promise.then(function successHandler(value) {
    //return to chain value
    return value;
}).catch(function rejectHandler(errorValue) {
    //to avoid conversion
    //throw to chain rejection
    throw errorValue;
    //OR return rejected promise
    //return $q.reject(errorValue);
});

不受欢迎的转换的最常见原因之一是无法返回或抛出任何内容:

//ERRONEOUS
function responseError(errorResponse) {
    console.log(errorResponse.status);
}    

在上面的示例中,拒绝处理程序错误地将拒绝转换为成功。当函数省略return语句或throw语句时,函数返回undefined。这会导致拒绝转换为成功,并以值undefined解析。

因此,在调试错误的转换时,请检查拒绝处理程序。然后寻找一个表现不佳的拦截器。

答案 1 :(得分:0)

我刚刚找到了错误的来源。我写了一个拦截器。我的目的只是设置我注入拦截器的服务的属性。因此,我只是没有以任何方式操纵拒绝,只是通过这样做:

&#13;
&#13;
function responseError(rejection) {
            busyService.isBusy = true;

            return rejection;
        }
&#13;
&#13;
&#13;

但这似乎使$ http.post成功。

如果我这样做,$ http.post是一个错误(按照需要):

&#13;
&#13;
        function responseError(rejection) {
            busyService.isBusy = true;

            var deferred = $q.defer();
            deferred.reject(rejection);
            return deferred.promise;
        }
&#13;
&#13;
&#13;

我仍然不知道为什么,还要进一步调查。如果有人可以进一步解释,那就太好了。