ASP.NET Web API之消息[攔截]處理(轉)

出處:http://www.cnblogs.com/Leo_wl/p/3238719.html

標題相當難取,內容也許和您想的不一樣,而且網上已經有很多這方面的資料了,我不過是在實踐過程中作下記錄。廢話少說,直接開始。

Exception


當服務端拋出未處理異常時,most exceptions are translated into an HTTP response with status code 500, Internal Server Error.當然我們也可以拋出一個特殊的異常HttpResponseException,它將被直接寫入響應流,而不會被轉成500。

復制代碼
復制代碼
public Product GetProduct(int id)
{Product item = repository.Get(id);if (item == null){throw new HttpResponseException(HttpStatusCode.NotFound);}return item;
}
復制代碼
復制代碼

有時要對服務端異常做一封裝,以便對客戶端隱藏具體細節,或者統一格式,那么可創建一繼承自System.Web.Http.Filters.ExceptionFilterAttribute的特性,如下:

復制代碼
復制代碼
public class APIExceptionFilterAttribute : ExceptionFilterAttribute
{public override void OnException(HttpActionExecutedContext context){//業務異常if (context.Exception is BusinessException){context.Response = new HttpResponseMessage { StatusCode = System.Net.HttpStatusCode.ExpectationFailed };BusinessException exception = (BusinessException)context.Exception;context.Response.Headers.Add("BusinessExceptionCode", exception.Code);context.Response.Headers.Add("BusinessExceptionMessage", exception.Message);}//其它異常else{context.Response = new HttpResponseMessage { StatusCode = System.Net.HttpStatusCode.InternalServerError };}}
}
復制代碼
復制代碼

然后將該Attribute應用到action或controller,或者GlobalConfiguration.Configuration.Filters.Add(new?APIExceptionFilterAttribute());使之應用于所有action(If you use the "ASP.NET MVC 4 Web Application" project template to create your project, put your Web API configuration code inside the?WebApiConfig?class, which is located in the App_Start folder:config.Filters.Add(newProductStore.NotImplExceptionFilterAttribute());)。當然,在上述代碼中,我們也可以在OnException方法中直接拋出HttpResponseException,效果是一樣的。

Note: Something to have in mind is that the ExceptionFilterAttribute will be ignored if the ApiController action method throws a HttpResponseException;If something goes wrong in the ExceptionFilterAttribute and an exception is thrown that is not of type HttpResponseException, a formatted exception will be thrown with stack trace etc to the client.

如果要返回給客戶端的不僅僅是一串字符串,比如是json對象,那么可以使用HttpError這個類。

以上知識主要來自Exception Handling in ASP.NET Web API。

ActionFilterAttribute、ApiControllerActionInvoker?


有時要在action執行前后做額外處理,那么ActionFilterAttribute和ApiControllerActionInvoker就派上用場了。比如客戶端請求發過來的參數為用戶令牌字符串token,我們要在action執行之前先將其轉為action參數列表中對應的用戶編號ID,如下:?

復制代碼
復制代碼
public class TokenProjectorAttribute : ActionFilterAttribute
{private string _userid = "userid";public string UserID{get { return _userid; }set { _userid = value; }}public override void OnActionExecuting(HttpActionContext actionContext){if (!actionContext.ActionArguments.ContainsKey(UserID)){//參數列表中不存在userid,寫入日志//……var response = new HttpResponseMessage();response.Content = new StringContent("用戶信息轉換異常.");response.StatusCode = HttpStatusCode.Conflict;//在這里為了不繼續走流程,要throw出來,才會立馬返回到客戶端throw new HttpResponseException(response);}//userid系統賦值actionContext.ActionArguments[UserID] = actionContext.Request.Properties["shumi_userid"];base.OnActionExecuting(actionContext);}public override void OnActionExecuted(HttpActionExecutedContext actionExecutedContext){base.OnActionExecuted(actionExecutedContext);}
}
復制代碼
復制代碼

ActionFilterAttribute如何應用到action,和前面的ExceptionFilterAttribute類似。

ApiControllerActionInvoker以上述Exception為例:

復制代碼
復制代碼
public class ServerAPIControllerActionInvoker : ApiControllerActionInvoker
{public override Task<HttpResponseMessage> InvokeActionAsync(HttpActionContext actionContext, CancellationToken cancellationToken){//對actionContext做一些預處理//……var result = base.InvokeActionAsync(actionContext, cancellationToken);if (result.Exception != null && result.Exception.GetBaseException() != null){var baseException = result.Exception.GetBaseException();if (baseException is BusinessException){return Task.Run<HttpResponseMessage>(() =>{var response = new HttpResponseMessage(HttpStatusCode.ExpectationFailed);BusinessException exception = (BusinessException)baseException;response.Headers.Add("BusinessExceptionCode", exception.Code);response.Headers.Add("BusinessExceptionMessage", exception.Message);return response;});}else{return Task.Run<HttpResponseMessage>(() => new HttpResponseMessage(HttpStatusCode.InternalServerError));}}return result;}
}
復制代碼
復制代碼

然后注冊至GlobalConfiguration.Configuration.Services中。由于ApiControllerActionInvoker乃是影響全局的,所以若要對部分action進行包裝處理,應該優先選擇ActionFilterAttribute。?

DelegatingHandler


前面的攔截都發生在請求已被路由至對應的action后發生,有一些情況需要在路由之前就做預先處理,或是在響應流返回過程中做后續處理,這時我們就要用到DelegatingHandler。比如對請求方的身份驗證,當驗證未通過時直接返回錯誤信息,否則進行后續調用。

復制代碼
復制代碼
public class AuthorizeHandler : DelegatingHandler
{private static IAuthorizer _authorizer = null;static AuthorizeHandler(){ }protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken){if (request.Method == HttpMethod.Post){var querystring = HttpUtility.ParseQueryString(request.RequestUri.Query);var formdata = request.Content.ReadAsFormDataAsync().Result;if (querystring.AllKeys.Intersect(formdata.AllKeys).Count() > 0){return SendError("請求參數有重復.", HttpStatusCode.BadRequest);}}//請求方身份驗證AuthResult result = _authorizer.AuthRequest(request);if (!result.Flag){return SendError(result.Message, HttpStatusCode.Unauthorized);}request.Properties.Add("shumi_userid", result.UserID);return base.SendAsync(request, cancellationToken);}private Task<HttpResponseMessage> SendError(string error, HttpStatusCode code){var response = new HttpResponseMessage();response.Content = new StringContent(error);response.StatusCode = code;return Task<HttpResponseMessage>.Factory.StartNew(() => response);}
}
復制代碼
復制代碼

?參考資料:

  • ASP.NET Web API Exception Handling
  • Implementing message handlers to track your ASP.NET Web API usage
  • MVC4 WebAPI(二)——Web API工作方式
  • Asp.Net MVC及Web API框架配置會碰到的幾個問題及解決方案

轉載請注明原文出處:http://www.cnblogs.com/newton/p/3238082.html

轉載于:https://www.cnblogs.com/smileberry/p/7093326.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/254208.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/254208.shtml
英文地址,請注明出處:http://en.pswp.cn/news/254208.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

無人駕駛遇見人工智能 百度將推有“大腦”的汽車

在日前舉行的中國云計算大會&#xff0c;百度高級副總裁、技術戰略委員會主席王勁表示&#xff0c;百度將在今年下半年推出無人駕駛汽車。不過&#xff0c;百度自己并不會造車&#xff0c;它將與第三方汽車廠商合作制造。據介紹&#xff0c;百度將利用現有的大數據、地圖、人工…

AdlinkMotionCardLibrary函數C++

#include "stdafx.h" #include "AdlinkMotionCardLibrary.h"extern "C" _declspec(dllexport) bool _stdcall MotionCardIni(I32& BoardId_InBits, I32 Mode) { try{//mode0&#xff1a;&#xff1a; 系統指定卡號 mode1&#xff1a;&am…

查看表的結構

describe 表名轉載于:https://www.cnblogs.com/dengyg200891/p/5966565.html

定制一個網絡文件系統

定制一個網絡文件系統【把pc上的文件系統掛接到開發板上面】 1、修改exports文件【PC上】一定要修改&#xff0c;否則不會成功 vi /etc/exports 修改為 /空格* 并保存 2、設置開發板上的IP地址 ifconfig eth0 192.168.0.11 up 3、設置PC上的IP地址 ifconfig et…

創建Hbase Hive外部表報錯: Unable to determine ZooKeeper ensemble

創建HBase的Hive外部表1: create external table ttt(rowkey string,info map<string,string>)STORED BY org.apache.hadoop.hive.hbase.HBaseStorageHandler WITH SERDEPROPERTIES ("hbase.columns.mapping" ":key,info:") TBLPROPERTIES ("h…

死磕算法之快速排序

版權聲明&#xff1a;本文為博主原創文章&#xff0c;未經博主允許不得轉載。博客源地址為zhixiang.org.cn https://blog.csdn.net/myFirstCN/article/details/80851021 學習更多算法系列請參考文章&#xff1a;死磕算法之匯總篇 快速排序是一個運用了分治法和遞歸算法的排序方…

九點標定進行仿射變換halcon仿真代碼

篩選出來的點得坐標已經顯示在PxRow、PxColunm里邊 * Image Acquisition 01: Code generated by Image Acquisition 01 read_image (Image, C:/Users/Administrator/Desktop/標定板圖片.png) dev_close_window () dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHand…

用SQL語句添加刪除修改字段_常用SQL

1.增加字段 alter table docdsp add dspcodechar(200)2.刪除字段 ALTER TABLE table_NAME DROP COLUMNcolumn_NAME3.修改字段類型 ALTER TABLE table_name ALTER COLUMNcolumn_name new_data_type4.sp_rename 改名 EXEC sp_rename [dbo].[Table_1].[fi…

DAVINCI開發原理之三----達芬奇編解碼引擎Codec Engine(CE)

DaVinci是DSP和ARM 雙核架構的SOC芯片。對芯片與外界的交互通過ARM端的Montavista Linux和相關驅動與應用程序來管理&#xff0c; DSP端只處理編解碼相關的算法。DSP和ARM之間的通訊和交互是通過引擎(Engine)和服務器(Server)來完成的。1. 編解碼引擎(Codec Engine) a. 核心引…

Windows操作系統安全加固

本文檔旨在指導系統管理人員或安全檢查人員進行Windows操作系統的安全合規性檢查和配置。 1. 賬戶管理和認證授權 1.1 賬戶 默認賬戶安全 禁用Guest賬戶。禁用或刪除其他無用賬戶&#xff08;建議先禁用賬戶三個月&#xff0c;待確認沒有問題后刪除。&#xff09;操作步驟 打開…

ios修改了coredata數據結構后,更新安裝會閃退

如果iOS App 使用到CoreData&#xff0c;并且在上一個版本上有數據庫更新&#xff08;新增表、字段等操作&#xff09;&#xff0c;那在覆蓋安裝程序時就要進行CoreData數據庫的遷移&#xff0c;具體操作如下&#xff1a; 1.選中你的mydata.xcdatamodeld文件&#xff0c;選擇菜…

TI DAVINCI開發原理(總共5部分)

2011-06-03 11:14:17| 分類&#xff1a; TI 達芬奇視頻處 | 標簽&#xff1a; |字號大中小訂閱 DAVINCI開發原理之一----ARM端開發環境的建立(DVEVM) 1. 對DAVINCI平臺&#xff0c;TI在硬件上給予雙核架構強有力的支撐&#xff0c;在DSP端用DSP/BIOS來支持音視頻算法的運行…

數據庫代碼寫法

1.創建數據庫create database test2; 2.刪除數據庫drop database test2; 3.創建表 create table ceshi (ids int auto_increment primary key,uid varchar(20),name varchar(20),class varchar(20),foreign key (class) references class(code) ); create table class (code …

random庫的使用

有關Python中random標準庫的使用 Python中關于隨機值的部分&#xff0c;借助的是根據當前的隨機種子&#xff0c;通過梅森旋轉算法&#xff0c;生成一段隨機序列。 基本隨機函數 random.seed(aNone)初始化給定的隨機種子&#xff0c;默認值為當前的系統時間。 random.random()生…

ThinkPHP--欄目增刪改查ADSF

<?php /*** 欄目發布*/ //V層&#xff0c;action/name值 action " :U( Admin/Cat/Cateadd )";/*** 添加欄目數據* C層&#xff0c;寫相應的方法進行數據添加*/ public function add(){if(!IS_POST){$this->display();}else{//var_dump($_POST);$catModelD…

模擬查找晶元的位置

通過模板匹配找到所有模板位置&#xff0c;并且當單擊某個模板時&#xff0c;選中某個模板 read_image (Image, C:/Users/22967/Desktop/晶圓找位置/0.bmp) dev_close_window () dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle) dev_display (Image)* draw_cir…

JavaScript常用函數之Eval()使用

eval() 功能&#xff1a;首先解釋Javascript代碼 然后執行它 用法&#xff1a;Eval&#xff08;codeString&#xff09; codeString是包含有javascript語句的字符串&#xff0c;在eval之后使用Javascript引擎編譯。即&#xff1a;eval函數可以把一個字符串當作一個javascript表…

初探數位dp

前言&#xff1a;這是蒟蒻第一次寫算法系列&#xff0c;請諸位大佬原諒文筆與排版。 一、導入 在刷題的時候&#xff0c;我們有時會見到這樣一類問題&#xff1a;在區間$[l,r]$內&#xff0c;共有多少個整數滿足某種條件。如果$l$和$r$間的差很小&#xff0c;我們可以考慮暴力枚…

Java演示手機發送短信驗證碼功能實現

我們這里采用阿里大于的短信API 第一步&#xff1a;登陸阿里大于&#xff0c;下載阿里大于的SDK a、在阿里大于上創建自己的應用 b、點擊配置管理中的驗證碼&#xff0c;先添加簽名&#xff0c;再配置短信模板 第二步&#xff1a;解壓相關SDK&#xff0c;第一個為jar包&#xf…

使用標定板對相機位姿進行估計

使用標定板幾個特定的點&#xff0c;來對相機相對標定板平面進行位姿估計。 首先進行相機的畸變校正&#xff0c;之后同個各個標定板間的圓點距離進行位姿估計。 gen_caltab (7, 7, 0.002, 0.5, C:/Users/22967/Desktop/新建文件夾/111.descr, C:/Users/22967/Desktop/新建文件…