.NetCore實(shí)現(xiàn)接口緩存的方法-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(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、問(wèn)題:我們平時(shí)做開(kāi)發(fā)的時(shí)候肯定都有用到緩存這個(gè)功能,一般寫法是在需要的業(yè)務(wù)代碼里讀取緩存、判斷是否存在、不存在則讀取數(shù)據(jù)庫(kù)再設(shè)置緩存這樣一個(gè)步驟。但是如果我們有很多地方業(yè)務(wù)都有用到緩存,我們就需要在每個(gè)地方都寫關(guān)于緩存的代碼,這樣會(huì)造成很多重復(fù)代碼,同時(shí)對(duì)業(yè)務(wù)侵入不利于后續(xù)的開(kāi)發(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ù)零侵入,那我們是不是想到了反射、特性呢?沒(méi)錯(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è)方法,相信很多小伙伴都用到過(guò),這里就不細(xì)說(shuō)了。那我們現(xiàn)在的解決方案是:在OnActionExecuting(執(zhí)行動(dòng)作方法前觸發(fā))里判斷是否存在緩存,如果存在則不去執(zhí)行接口業(yè)務(wù),直接返回?cái)?shù)據(jù)。還有一個(gè)問(wèn)題,一般接口都會(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è)置較短過(guò)期時(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://muchs.cn/article26/ddcejg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供營(yíng)銷型網(wǎng)站建設(shè)動(dòng)態(tài)網(wǎng)站、Google、定制開(kāi)發(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)

商城網(wǎng)站建設(shè)