這篇文章將為大家詳細(xì)講解有關(guān).NetCore實(shí)現(xiàn)接口緩存的方法,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個(gè)參考,希望大家閱讀完這篇文章后對(duì)相關(guān)知識(shí)有一定的了解。
目前創(chuàng)新互聯(lián)已為數(shù)千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁(yè)空間、網(wǎng)站托管、服務(wù)器租用、企業(yè)網(wǎng)站設(shè)計(jì)、周村網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。1、問題:我們平時(shí)做開發(fā)的時(shí)候肯定都有用到緩存這個(gè)功能,一般寫法是在需要的業(yè)務(wù)代碼里讀取緩存、判斷是否存在、不存在則讀取數(shù)據(jù)庫(kù)再設(shè)置緩存這樣一個(gè)步驟。但是如果我們有很多地方業(yè)務(wù)都有用到緩存,我們就需要在每個(gè)地方都寫關(guān)于緩存的代碼,這樣會(huì)造成很多重復(fù)代碼,同時(shí)對(duì)業(yè)務(wù)侵入不利于后續(xù)的開發(fā)維護(hù)。
2、一般的解決辦法是將緩存的功能提取出來(lái),然后在需要用到緩存的地方調(diào)用即可。這樣確實(shí)減少了很多重復(fù)代碼,但這樣還是會(huì)存在整個(gè)項(xiàng)目通用的緩存功能侵入業(yè)務(wù)代碼,那我們有什么辦法將緩存功能完全提取出來(lái),達(dá)到業(yè)務(wù)代碼零侵入呢?
3、既然我們緩存存的是接口的業(yè)務(wù)數(shù)據(jù),那么為何我們不能直接把整個(gè)接口緩存起來(lái)呢,即將整個(gè)接口返回的數(shù)據(jù)緩存?同時(shí)要達(dá)到業(yè)務(wù)零侵入,那我們是不是想到了反射、特性呢?沒錯(cuò),我們使用的就是ActionFilterAttribute,關(guān)于ActionFilterAttribute無(wú)非就是OnActionExecuting(執(zhí)行動(dòng)作方法前觸發(fā))、OnActionExecuted(執(zhí)行動(dòng)作方法后觸發(fā))、OnResultExecuting(在執(zhí)行操作結(jié)果之前觸發(fā))、OnResultExecuted(在執(zhí)行操作結(jié)果之后觸發(fā))這四個(gè)方法,相信很多小伙伴都用到過,這里就不細(xì)說(shuō)了。那我們現(xiàn)在的解決方案是:在OnActionExecuting(執(zhí)行動(dòng)作方法前觸發(fā))里判斷是否存在緩存,如果存在則不去執(zhí)行接口業(yè)務(wù),直接返回?cái)?shù)據(jù)。還有一個(gè)問題,一般接口都會(huì)有入?yún)ⅲ雲(yún)⒉煌敵龅臄?shù)據(jù)也不同(比如我有一個(gè)分頁(yè)的接口,傳的page參數(shù)不同,得到的結(jié)果也不同),這個(gè)怎么解決呢?我們只需要把接口所有參數(shù)拼湊起來(lái),然后MD5加密成一個(gè)字符串,將其作為緩存的key,那么即使同一個(gè)接口、參數(shù)不同也會(huì)得到不同的key。
4、廢話不多說(shuō),直接上代碼。
public class ApiCache : ActionFilterAttribute { /// <summary> /// Header是否參與緩存驗(yàn)證 /// </summary> public bool SignHeader = false; /// <summary> /// 緩存有效時(shí)間(分鐘) /// </summary> public int CacheMinutes = 5;/// <summary> /// /// </summary> /// <param name="SignHeader">Header是否參與請(qǐng)求體簽名</param> /// <param name="CacheMinutes">緩存有效時(shí)間(分鐘)</param> public ApiCache(bool SignHeader = false, int CacheMinutes = 5) { this.SignHeader = SignHeader; this.CacheMinutes = CacheMinutes; } public override void OnActionExecuting(ActionExecutingContext filterContext) { //請(qǐng)求體簽名 string cacheKey = getKey(filterContext.HttpContext.Request); //根據(jù)簽名查詢緩存 string data = CsRedisHepler.Get(cacheKey); if (!string.IsNullOrWhiteSpace(data)) { //有緩存則設(shè)置返回信息 var content = new Microsoft.AspNetCore.Mvc.ContentResult(); content.Content = data; content.ContentType = "application/json; charset=utf-8"; content.StatusCode = 200; filterContext.HttpContext.Response.Headers.Add("ContentType", "application/json; charset=utf-8"); filterContext.HttpContext.Response.Headers.Add("CacheData", "Redis"); filterContext.Result = content; } } public override void OnActionExecuted(ActionExecutedContext filterContext) { base.OnActionExecuted(filterContext); } public override void OnResultExecuting(ResultExecutingContext filterContext) { base.OnResultExecuting(filterContext); } public override void OnResultExecuted(ResultExecutedContext filterContext) { if (filterContext.HttpContext.Response.Headers.ContainsKey("CacheData")) return; //獲取緩存key string cacheKey = getKey(filterContext.HttpContext.Request); var data = JsonSerializer.Serialize((filterContext.Result as Microsoft.AspNetCore.Mvc.ObjectResult).Value); //如果緩存null,則設(shè)置較短過期時(shí)間(此處是防止緩存穿透) var disData = JsonSerializer.Deserialize<Dictionary<string, object>>(data); if(disData.ContainsKey("data") && disData["data"]==null) { CacheMinutes = 1; } CsRedisHepler.Set(cacheKey, data, TimeSpan.FromMinutes(CacheMinutes)); } /// <summary> /// 請(qǐng)求體MDH簽名 /// </summary> /// <param name="request"></param> /// <returns></returns> private string getKey(HttpRequest request) { var keyContent = request.Host.Value + request.Path.Value + request.QueryString.Value + request.Method + request.ContentType + request.ContentLength; try { if (request.Method.ToUpper() != "DELETE" && request.Method.ToUpper() != "GET" && request.Form.Count > 0) { foreach (var item in request.Form) { keyContent += $"{item.Key}={item.Value.ToString()}"; } } } catch (Exception e) { } if (SignHeader) { var hs = request.Headers.Where(a => !(new string[] { "Postman-Token", "User-Agent" }).Contains(a.Key)).ToDictionary(a => a); foreach (var item in hs) { keyContent += $"{item.Key}={item.Value.ToString()}"; } } //md5加密 return CryptographyHelper.MD5Hash(keyContent); }
網(wǎng)站欄目:.NetCore實(shí)現(xiàn)接口緩存的方法-創(chuàng)新互聯(lián)
URL網(wǎng)址:http://www.rwnh.cn/article26/ddcejg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷型網(wǎng)站建設(shè)、動(dòng)態(tài)網(wǎng)站、Google、定制開發(fā)、電子商務(wù)、網(wǎng)站維護(hù)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容