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);
            }
        };
  • 相关阅读:
    【贪心+DFS】D. Field expansion
    【贪心+博弈】C. Naming Company
    【dp】E. Selling Souvenirs
    【multimap的应用】D. Array Division
    内存变量边界对齐
    3.8 高级检索方式(二)
    3.7 高级检索方式(一)
    openGL加载obj文件+绘制大脑表层+高亮染色
    3.6 Lucene基本检索+关键词高亮+分页
    3.5 实例讲解Lucene索引的结构设计
  • 原文地址:https://www.cnblogs.com/shawnhu/p/8425562.html
Copyright © 2011-2022 走看看