如何在AngularJS服务中捕获HttpResponseException?

时间:2016-08-16 17:43:56

标签: angularjs asp.net-mvc asp.net-web-api2

在我的WebAPI控制器中,我有一个返回正确结果或HttpResponseException的函数。

public async Task<SearchResult> Search([FromUri] SearchArguments args)
    {
        try
        {
            SearchResult searchResult = await _case.Search(args, true);

            string validationError = searchResult.Error;

            if (!string.IsNullOrEmpty(validationError))
            {
                throw new HttpResponseException(new HttpResponseMessage(System.Net.HttpStatusCode.BadRequest)
                {
                    ReasonPhrase = string.Format("Could not find the case. {0}", validationError)
                });
            }

            return searchResult;
        }
        catch (Exception ex)
        {
            throw new HttpResponseException(new HttpResponseMessage(System.Net.HttpStatusCode.InternalServerError)
            {
                ReasonPhrase = ex.Message
            });
        }
    }

在angularjs服务中使用它,使用如下的http get请求调用此函数。

svc.Search = function (searchArgs) {
        var deferred = $q.defer();
        var url = 'sci/case/search?';

        $http.get(sc.baseURL + url, { params: searchArgs }).
            then(function (r) {
                if (!r || !r.data) {
                    console.log('Error: No Data Returned');
                    deferred.reject('No Data Returned');
                }
                deferred.resolve(r.data);
            }, function (err) {
                console.log('Error: ' + err);
                deferred.reject(err);
            });
        return deferred.promise;
}

如果成功结果,则r.data包含预期结果。但是当从控制器抛出HttpResponseException时,我无法捕获ReasonPhrase。我需要在控制器中格式化自定义错误消息并在UI中显示它们。 HttpResponseException是否适合完成此操作?感谢您的任何建议。

2 个答案:

答案 0 :(得分:1)

您应该在错误回调中读取statusText属性值。 response对象的statusText属性是一个字符串值,其中包含响应的状态文本。 HttpResponseException会将ReasonPhrase值设置为响应的状态文本。

 $http.get(sc.baseURL + url, { params: searchArgs }).
            then(function (r) {
                if (!r || !r.data) {
                    console.log('Error: No Data Returned');
                    deferred.reject('No Data Returned');
                }
                deferred.resolve(r.data);
            }, function (err) {
                var errMsg =  err.statusText;
                alert(errMsg);               
            });

答案 1 :(得分:1)

当您抛出异常时,执行流程将被中断,并且将返回内部服务器错误。您应该处理错误并返回错误消息作为结果。

我认为您最好定义一个类来表示API调用结果,如下所示:

public class ApiCallResult {
  public ApiCallResult (){
        Succeeded = true;
  }
  public object Result {get;set;}
  public bool Succeeded{get;set;}
  public string Message {get;set;}
}

然后:

public async Task<SearchResult> Search([FromUri] SearchArguments args)
    {
        var result = new ApiCallResult (); 
        try
        {

            SearchResult searchResult = await _case.Search(args, true);
            result.Result = searchResult;

            string validationError = searchResult.Error;

            if (!string.IsNullOrEmpty(validationError))
            {                    
                 result.Message = string.Format("Could not find the case");
                 result.Succeeded = false;
            }
        }
        catch (Exception ex)
        {
                 result.Message = ex.Message;
                 result.Succeeded = false;

        }

        return result;
    }

和内部视图:

svc.Search = function (searchArgs) {
        var deferred = $q.defer();
        var url = 'sci/case/search?';

        $http.get(sc.baseURL + url, { params: searchArgs }).
            then(function (r) {
                if (!r || !r.Succeeded) {
                    console.log('Error: No Data Returned');
                    deferred.reject('No Data Returned');
                }
                deferred.resolve(r.Result.data);
            }, function (r) {
                console.log('Error: ' + r.Message);
                deferred.reject(r.Message);
            });
        return deferred.promise;
}