.NET中間件與VUE攔截器聯(lián)合使用詳情
前言:
工作中遇見的問題,邊學(xué)邊弄,記錄一下Vue的UI庫(kù)使用的是antvue 3.2.9版本的。
業(yè)務(wù)邏輯
特性:
//特性 public class ModelEsignNameAttribute : Attribute { public ModelEsignNameAttribute(string nameProp, string id, string reversion = "", ModelESignType eSignType = ModelESignType.Modeling, string middleModelId = "") { } }
接口加上特性:
/// <summary> /// 添加或者修改方法 /// </summary> /// <param name="input"></param> /// <returns></returns> //特性上添加參數(shù)的地址 [ModelEsignName("Bolg.BolgBaseEditDto.BolgName", "Document.Id", "Bolg.BolgRevision")] public async Task<Output> CreateOrUpdate(CreateOrUpdateBolgInput input) { var doc = await _XXXXManager.FindRdoById(input.Bolg.Id.Value); // 文檔id為空,新增 if (doc == null || !input.Bolg.BolgBaseId.HasValue) { return await this.Create(input.Bolg); } // 更新 return await this.Update(input.Bolg); }
中間件代碼:
namespace GCT.MedPro.Middleware { public class ModelESignCheckMiddleware : IMiddleware { #region 依賴注入等內(nèi)容 .... #endregion public async Task InvokeAsync(HttpContext context, RequestDelegate next) { if (await ShouldCheckESign(context)) { // 不需要電子簽名 await next(context); } } /// <summary> /// 是否需要攔截 /// </summary> /// <param name="actionContext"></param> /// <returns></returns> private async Task<bool> ShouldCheckESign(HttpContext actionContext) { var whetherSignature = true; var request = actionContext.Request;//獲取請(qǐng)求值 var currentUser = actionContext.User.Identity.Name; var serviceAction = actionContext .GetEndpoint()? .Metadata .GetMetadata<ControllerActionDescriptor>(); if (serviceAction == null) { return whetherSignature; } //通過接口特性來(lái)篩選是否需要進(jìn)行攔截 var attrObj = serviceAction.MethodInfo.CustomAttributes .FirstOrDefault(x => x.AttributeType == typeof(ModelEsignNameAttribute)); if (attrObj == null) { return whetherSignature; } string inputbody = default; actionContext.Request.EnableBuffering(); //Post請(qǐng)求獲取請(qǐng)求參數(shù),轉(zhuǎn)換JSON if (request.Method.ToLower().Equals("post")) { var requestReader = new StreamReader(actionContext.Request.Body); var body = await requestReader.ReadToEndAsync(); inputbody = UpperFirst(body); //首字母大寫 全局搜索可得下方有 } else //GET請(qǐng)求以及其他方式獲取 { var reqString = request.QueryString.Value.Remove(0, 1); string[] parts = reqString.Split("&"); JObject json = new JObject(); foreach (string part in parts) { String[] keyVal = part.Split("="); json.Add(keyVal[0], keyVal[1]); } inputbody = JsonConvert.SerializeObject(json); inputbody = UpperFirst(inputbody); } var inputObj = JObject.Parse(inputbody);//轉(zhuǎn)換JObject #region 獲取特性傳入的參數(shù),,總五位參數(shù) var actionName = serviceAction.ActionName; var namePath = attrObj.ConstructorArguments[0].Value.ToString(); var idPath = attrObj.ConstructorArguments[1].Value.ToString(); var revsionPath = attrObj.ConstructorArguments[2].Value.ToString(); var typePath = (ModelESignType)attrObj.ConstructorArguments[3].Value; var middlePath = attrObj.ConstructorArguments[4].Value.ToString(); #endregion var middleModelId = GetValueName(inputObj, middlePath);//通過JObject獲取對(duì)應(yīng)值 //接口控制器名稱 var typeName = serviceAction.ControllerTypeInfo.FullName; //重置請(qǐng)求Body指針 actionContext.Request.Body.Position = 0; //驗(yàn)證方法,自己寫個(gè),自已業(yè)務(wù)的處理驗(yàn)證 var output = await CheckSign(middleModelId); if (!output.SignStatus) { actionContext.Request.EnableBuffering(); Stream originalBody = actionContext.Response.Body; try { using (var ms = new MemoryStream()) { //修改響應(yīng)狀態(tài)麻420 actionContext.Response.Body = ms; actionContext.Response.StatusCode = 420; ms.Position = 0; //寫入數(shù)據(jù) var responseBody = TextJosn.JsonSerializer.Serialize(output); var memoryStream = new MemoryStream(); var sw = new StreamWriter(memoryStream); //自己編輯的實(shí)體寫入響應(yīng)體 sw.Write(responseBody); sw.Flush(); //重置響應(yīng)指針 memoryStream.Position = 0; //復(fù)制到原body上 await memoryStream.CopyToAsync(originalBody); } } finally { actionContext.Response.Body = originalBody; actionContext.Request.Body.Position = 0; } whetherSignature = false; } else { if (!string.IsNullOrWhiteSpace(output.ErrorMessage)) { var serializerSettings = new JsonSerializerSettings { // 設(shè)置為駝峰命名 ContractResolver = new Newtonsoft.Json.Serialization .CamelCasePropertyNamesContractResolver() }; //錯(cuò)誤友好提示,適配中間件中拋出錯(cuò)誤,修改響應(yīng)體 var exception = new UserFriendlyException(output.ErrorMessage); actionContext.Response.StatusCode = 500; actionContext.Response.ContentType = "application/json; charset=utf-8"; //寫入 await actionContext.Response.WriteAsync( JsonConvert.SerializeObject( new AjaxResponse( _errorInfoBuilder.BuildForException(exception), true ), serializerSettings ) ); whetherSignature = false; } } return whetherSignature; } //取出json的Name值 private string GetValueName(JObject inputObj, string path) { string result = null; if (!string.IsNullOrWhiteSpace(path)) { result = inputObj.SelectToken(path).ToObject<string>(); } return result; } /// <summary> /// Json字符串首字母轉(zhuǎn)大寫 /// </summary> /// <param name="strJsonData">json字符串</param> /// <returns></returns> public static string UpperFirst(string strJsonData) { MatchCollection matchCollection = Regex.Matches(strJsonData, "\\\"[a-zA-Z0-9]+\\\"\\s*:"); foreach (Match item in matchCollection) { string res = Regex.Replace(item.Value, @"\b[a-z]\w+", delegate (Match match) { string val = match.ToString(); return char.ToUpper(val[0]) + val.Substring(1); }); strJsonData = strJsonData.Replace(item.Value, res); } return strJsonData; } } }
Vue攔截器,攔截失敗的響應(yīng),狀態(tài)碼為420的,中間件修改的響應(yīng)的狀態(tài)碼:
import { AppConsts } from '/@/abpPro/AppConsts'; import { abpService } from '/@/shared/abp'; import { Modal } from 'ant-design-vue'; import axios, { AxiosResponse } from 'axios'; import abpHttpConfiguration from './abp-http-configuration.service'; const apiHttpClient = axios.create({ baseURL: AppConsts.remoteServiceBaseUrl, timeout: 300000, }); // 請(qǐng)求攔截器 apiHttpClient.interceptors.request.use( (config: any) => { // .... return config; }, (error: any) => { return Promise.reject(error); }, ); // 響應(yīng)攔截器 apiHttpClient.interceptors.response.use( (response: AxiosResponse) => { // 響應(yīng)成功攔截器 if (response.data.__abp) { response.data = response.data.result; } return response; }, (error: any) => { // 響應(yīng)失敗攔截器 //方法里存在異步,使用一個(gè)Promise包裹起來(lái) return new Promise((resolve, reject) => { // 關(guān)閉所有模態(tài)框 Modal.destroyAll(); const errorResponse = error.response; const ajaxResponse = abpHttpConfiguration.getAbpAjaxResponseOrNull(error.response); if (ajaxResponse != null) { abpHttpConfiguration.handleAbpResponse(errorResponse, ajaxResponse); reject(error); } else { if (errorResponse.status == 420) { //abpHttpConfiguration中自己寫的一個(gè)模態(tài)框彈窗,把響應(yīng)數(shù)據(jù)傳入其中 abpHttpConfiguration.needIntercept(errorResponse.data) .toPromise()//Observable轉(zhuǎn)Promise .then((value) => { if (value) { // resolve 原先的請(qǐng)求地址,重發(fā)請(qǐng)求 resolve(apiHttpClient(errorResponse.config)); } else { reject(error); } }); } else { abpHttpConfiguration.handleNonAbpErrorResponse(errorResponse); reject(error); } } }); }, ); export default apiHttpClient;
模態(tài)框彈窗,返回的bool類型:
//是否驗(yàn)證需求通過彈窗 needIntercept(error): Observable<Boolean> { return new Observable<Boolean>((obs) => { if (error != undefined && error.SignStatus != null && !error.SignStatus) { //彈出模態(tài)框 this.modalCreate(error).subscribe( (b) => { obs.next(b); obs.complete(); }, (error) => console.log(error, 123), () => { obs.next(false); obs.complete(); }, ); } else { obs.next(false); obs.complete(); } }); } //電子簽名彈窗 modalCreate(responseBody: any): Observable<Boolean> { let sub; if (!responseBody.IsAccountSign) { //彈出模態(tài)框,指定的組件GESignNameComponent ,傳入?yún)?shù) sub = modalHelper.create( GESignNameComponent, { relationId: responseBody.ModelSignNameId, listEsignRequirementId: responseBody.ListSignRequirementId, }, ); } else { //彈出模態(tài)框,GESignNameAccountComponent ,傳入?yún)?shù) sub = modalHelper.create( GESignNameAccountComponent, { relationId: responseBody.ModelSignNameId, listEsignRequirementId: responseBody.ListSignRequirementId, }, ); } return sub; }
到此這篇關(guān)于.NET中間件與VUE攔截器聯(lián)合使用詳情的文章就介紹到這了,更多相關(guān).NET VUE攔截器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
ASP.NET Core中使用令牌桶限流的實(shí)現(xiàn)
這篇文章主要介紹了ASP.NET Core中使用令牌桶限流的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-04-04ASP.NET中實(shí)現(xiàn)Form表單字段值自動(dòng)填充到操作模型中
這篇文章主要介紹了ASP.NET中實(shí)現(xiàn)Form表單字段值自動(dòng)填充到操作模型中,本文模仿MVC模式中的自動(dòng)映射表單了模型,使用泛型和反射實(shí)現(xiàn),需要的朋友可以參考下2015-06-06使用ASP.Net?WebAPI構(gòu)建REST服務(wù)
這篇文章介紹了使用ASP.Net?WebAPI構(gòu)建REST服務(wù)的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06SQL Server數(shù)據(jù)庫(kù)連接 Web.config如何配置
以下的文章主要描述的是Web.config正確配置SQL Server數(shù)據(jù)庫(kù)連接的實(shí)際擦步驟。我們以圖文結(jié)合的方式對(duì)其有個(gè)更好的說(shuō)明,需要的朋友可以參考下2015-10-10ASP.Net Core基于ABP架構(gòu)配置To Json序列化
這篇文章介紹了ASP.Net Core基于ABP架構(gòu)配置To Json序列化的方法,文中通過示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-06-06基于ASP.NET的lucene.net全文搜索實(shí)現(xiàn)步驟
使用lucene.net搜索分為兩個(gè)部分,首先是創(chuàng)建索引,創(chuàng)建文本內(nèi)容的索引,其次是根據(jù)創(chuàng)建的索引進(jìn)行搜索, 感興趣的朋友可以了解下或許對(duì)你有所幫助2013-02-02System.Timers.Timer定時(shí)執(zhí)行程序示例代碼
如果是某個(gè)邏輯功能的定時(shí),可以將code放到邏輯功能的類的靜態(tài)構(gòu)造函數(shù)中,在該邏輯類第一次執(zhí)行時(shí),靜態(tài)構(gòu)造函數(shù)會(huì)被調(diào)用,則定時(shí)自然啟動(dòng)2013-06-06ASP.Net執(zhí)行cmd命令的實(shí)現(xiàn)代碼
ASP.Net執(zhí)行cmd命令的實(shí)現(xiàn)代碼,需要的朋友可以參考下。2011-02-02