一、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);
}
};

ASP.NET Web API 异常处理 HttpResponseException 以及Angularjs获取异常信息并提示的更多相关文章

  1. 在 ASP.NET Web API 中使用 Attribute 统一处理异常

    并非所有的异常都需要 try-catch 进行重复的处理,这会导致大量的重复性代码,一旦后续系统出现异常处理机制的修改,随着代码量增多,修改也会变的更加困难. ASP.NET Web API 中特别增 ...

  2. ASP.NET Web API系列教程目录

    ASP.NET Web API系列教程目录 Introduction:What's This New Web API?引子:新的Web API是什么? Chapter 1: Getting Start ...

  3. ASP.NET Web API系列教程(目录)(转)

    注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP.NET Web API.这是一个用来在.NET平台上建立HTTP服务的Web API框架,是微软的又一项令人振奋的技术.目前,国内 ...

  4. Implement JSON Web Tokens Authentication in ASP.NET Web API and Identity 2.1 Part 3 (by TAISEER)

    http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-api-an ...

  5. [转]ASP.NET Web API系列教程(目录)

    本文转自:http://www.cnblogs.com/r01cn/archive/2012/11/11/2765432.html 注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP ...

  6. 剖析Asp.Net Web API路由系统---WebHost部署方式

    上一篇我们剖析了Asp.Net路由系统,今天我们再来简单剖析一下Asp.Net Web API以WebHost方式部署时,Asp.Net Web API的路由系统内部是怎样实现的.还是以一个简单实例开 ...

  7. Asp.Net Web API 2第七课——Web API异常处理

    前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文主要来讲解Asp.Ne ...

  8. 【ASP.NET Web API教程】4.3 ASP.NET Web API中的异常处理

    原文:[ASP.NET Web API教程]4.3 ASP.NET Web API中的异常处理 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面的内 ...

  9. 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(3)

    chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...

随机推荐

  1. JoyOI1935 导弹防御塔

    原题链接 首先可以二分答案,然后考虑检验答案. 我们可以对炮塔进行拆点,即能发射\(x\)颗导弹就拆成\(n\times x\)个点,作为一个集合,另一个集合则是\(m\)个侵入者,然后对于能在剩余时 ...

  2. Luogu 4556 雨天的尾巴 - 启发式合并线段树

    Solution 用$col$记录 数量最多的种类, $sum$记录 种类$col$ 的数量. 然后问题就是树上链修改, 求 每个节点 数量最多的种类. 用树上差分 + 线段树合并更新即可. Code ...

  3. BZOJ 3932 [CQOI2015]任务查询系统 - 差分 + 主席树

    Solution 差分就好了, 在$s_i$ 的点+1, $e_i + 1$ 的点 - 1. 查询的时候注意$l == r$ 要返回 $k * b[l]$ ,而不是$sum[node] $因为当前位置 ...

  4. 谁说delphi没有IOCP库,delphi新的IOCP类库,开源中: DIOCP组件JSON流模块说明

    单元:JSonStream.pas 简介:本单元实现 流和json对象的相互转换,其中有一些保留的key. 依赖:superobject 保留key: __result.errCode  返回的错误编 ...

  5. pycharm创建新django app

    Tools -> Run manage.py task -> startapp appName(你的App名称) 或者 optin + R  -> startapp appName( ...

  6. Spring访问数据库(方式上跟HQL类似,每行记录映射一个实体类)

    看了这篇技术博客,觉得收获较大,收藏了:http://sarin.iteye.com/blog/875915

  7. Hadoop的本地库(Native Libraries)介绍

    Hadoop是使用Java语言开发的,但是有一些需求和操作并不适合使用java,所以就引入了本地库(Native Libraries)的概念,通过本地库,Hadoop可以更加高效地执行某一些操作. 目 ...

  8. java基本例子

    文件结构 D:\jp\jarDemo\IAmMainClass.java import iAmPackage.*; public class IAmMainClass { public static ...

  9. 阻塞式简易http服务器

    说明         使用java.net包的ServerSocket也是阻塞的,所以下面的实例把ServerSocketChannel换成ServerSocket效果一样. 后台代码 package ...

  10. 20155312 张竞予 2006-2007-2 《Java程序设计》第四周学习总结

    20155312 2006-2007-2 <Java程序设计>第四周学习总结 课堂笔记 Ctrl+shift+T调出三个窗口,分别是"vi编写代码","jav ...