zoukankan      html  css  js  c++  java
  • ASP.NET Web API 异常处理 HttpResponseException 以及Angularjs获取异常信息并提示

    一、HttpResponseException

      如果一个Web API控制器抛出一个未捕捉异常,默认地,大多数异常都会被转化成一个带有状态码“500 – 内部服务器错误”的HTTP响应。HttpResponseException(HTTP响应异常)类型会返回你在异常构造器中指定的任何HTTP状态码。例如,在以下方法中,如果id参数非法,会返回“404 — 未找到”。

    public Product GetProduct(int id) 
    { 
        Product item = repository.Get(id); 
        if (item == null) 
        { 
         //指定响应状态码
    throw new HttpResponseException(HttpStatusCode.NotFound); } return item; }

      为了对响应进行更多控制,你也可以构造整个响应消息HttpResponseMessage,并用HttpResponseException来包含它:

    public Product GetProduct(int id) 
    { 
        Product item = repository.Get(id); 
        if (item == null) 
        { 
            var resp = new HttpResponseMessage(HttpStatusCode.NotFound) 
            { 
                Content = new StringContent(string.Format("No product with ID = {0}", id)), 
                ReasonPhrase = "Product ID Not Found" 
            } 
         //包含一个HttpResponseMessage
    throw new HttpResponseException(resp); } return item; }

    二、Exception Filters

      继承ExceptionFilterAttribute,重写OnException,最后都是抛出HttpResponseException,包含一个HttpResponseMessage,调用客户端可以获取该异常信息,进行相应处理。

     public class ExceptionHandlingAttribute : ExceptionFilterAttribute
        {
            public override void OnException(HttpActionExecutedContext context)
            {
                if (context.Exception != null && !(context.Exception is HttpResponseException))
                {
                    MetricsConfig.MarkException(context.Exception);
    
                    if (context.Exception is UnauthorizedAccessException)
                    {
                        throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized));
                    }
    
                    var exceptionData = new ExceptionData
                    {
                        Name = context.Exception.GetType().Name,
                        Message = context.Exception.GetBaseException().Message
                    };
    
                    if (context.Exception is ApplicationException)
                    {
                        exceptionData.Message = context.Exception.Message;
                        var businessException = context.Exception as CustomBusinessException;
                        if (businessException != null)
                        {
                            exceptionData.Data = businessException.Data;
                        }
                    }
    
                    throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError)
                    {
                        Content = new ObjectContent<ExceptionData>(exceptionData, JsonFormatter),
                        ReasonPhrase = context.Exception.GetType().Name
                    });
    
                }
            }
    
            private JsonMediaTypeFormatter _JsonFormatter;
            private JsonMediaTypeFormatter JsonFormatter
            {
                get
                {
                    if (_JsonFormatter == null)
                    {
                        _JsonFormatter = new JsonMediaTypeFormatter();
                        _JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();
                    }
                    return _JsonFormatter;
                }
            }
    
            // A simple class for generate response with json content.
            public class ExceptionData
            {
                public string Name { get; set; }
                public string Message { get; set; }
                public string Data { get; set; }
            }
        }

      注册:

      以下是全局注册,当然也可以在Controller或Action上标注

    public static class WebApiConfig
        {
            public static void Register(HttpConfiguration config)
            {
               
                // register exception handler.
                config.Filters.Add(new ExceptionHandlingAttribute());
    
            }
        }

    三、客户端获取异常

      通过AngularJs中AOP拦截响应实现

    // apiInterceptor is responsible to handle the aspect of each request and response.
    webservices.factory('apiInterceptor',
    ['$q', '$log', '$injector', 'loginContext', 'eventAggregator', function ($q, $log, $injector, loginContext, eventAggregator) {
        'use strict';
    
        var apiToken = loginContext.apiToken;
        var tokenType = loginContext.tokenType;
        var webApiHostUrl = loginContext.apiHost + "/api/v1";
    
        return {
            //token save to services for further usage
            tokenType: tokenType,
            apiToken: apiToken,
            webApiHostUrl: webApiHostUrl,
    
            // On request success 请求拦截
            request: function (config) {
                if (config.isWebApiRequest && !config.isPlugin) {
              //地址上都自动附加上/api/v1 config.url
    = (config.mkApiUrl || webApiHostUrl) + config.url; config.headers = config.headers || {};
              //添加Authorization,用tokeentype token格式来定义 ,如 ‘bearer sfsfsfsfsdf=sfsf+...’
    config.headers.Authorization
    = tokenType + ' ' + (config.mkToken || apiToken); var specificOfficeId = Ares.specificOfficeUtil.getOfficeId(); if (specificOfficeId) { config.headers["specific-office-id"] = specificOfficeId; } } else if (config.handleApiRequest) { config = config.handleApiRequest(config); } return config; }, // On request failure requestError: function (rejection) { $log.error(rejection); // Contains the data about the error on the request. // Return the promise rejection. return $q.reject(rejection); }, // On response failture,响应拦截 responseError: function (response) { $log.error(response); // Contains the data about the error. if (response.status === 401) {//状态码判断 //window.location = '/logoff'; Ares.logOff(); } else if (response.data) {//返回内容判断 if (response.data.name == 'TenantInactiveException') { aresMaintainUtil.goToTenantInactivePage(); }
              //发布一个订阅,导致弹出一个对话框 eventAggregator.publish(eventAggregator.events.ApiErrorHappened, response,
    'apiInterceptor'); } else if (response.status === 0) { var isSaasApi = true; if (response.config && response.config.url.indexOf('//marketcenter') > -1) { isSaasApi = false; } if (isSaasApi) { aresMaintainUtil.ensureInMaintainMode().then(function (isInMaintainMode) { if (isInMaintainMode) { aresMaintainUtil.goToMaintainPage(); } }); } } // Return the promise rejection. return $q.reject(response); } }; }]); //Aop拦截,对响应 webservices.config(['$httpProvider', function ($httpProvider) { $httpProvider.interceptors.push('apiInterceptor'); }]);

      注册订阅:

    var subscribeEvents = function () {
            eventAggregator.subscribe($scope, eventAggregator.events.ApiErrorHappened, onApiErrorHappened);
        };
    
        //弹出提示对话框
        var onApiErrorHappened = function (event, args) {
            if (args.data.name == 'MyOperationException'
                    || args.data.name == 'CustomBusinessException') {
                customDialog.info('系统提示', args.data.message);
            }
        };
  • 相关阅读:
    UVa 10118 记忆化搜索 Free Candies
    CodeForces 568B DP Symmetric and Transitive
    UVa 11695 树的直径 Flight Planning
    UVa 10934 DP Dropping water balloons
    CodeForces 543D 树形DP Road Improvement
    CodeForces 570E DP Pig and Palindromes
    HDU 5396 区间DP 数学 Expression
    HDU 5402 模拟 构造 Travelling Salesman Problem
    HDU 5399 数学 Too Simple
    CodeForces 567F DP Mausoleum
  • 原文地址:https://www.cnblogs.com/shawnhu/p/8425562.html
Copyright © 2011-2022 走看看