最近的項目系之3——core3.0整合Senparc

来源:https://www.cnblogs.com/guokun/archive/2019/11/19/11891801.html
-Advertisement-
Play Games

1、前言 既然是.net下微信開發,自然少不了Senparc,可以說這個框架的存在, 至少節省了微信相關工作量的80%。事實上,項目開始前,還糾結了下是Java還是core,之所以最終選擇core,除了情懷外,更重要的便是這個微信開發框架的存在。本項目的整合方式,極大程度上參考了Senparc官方的 ...


1、前言

  既然是.net下微信開發,自然少不了Senparc,可以說這個框架的存在, 至少節省了微信相關工作量的80%。事實上,項目開始前,還糾結了下是Java還是core,之所以最終選擇core,除了情懷外,更重要的便是這個微信開發框架的存在。本項目的整合方式,極大程度上參考了Senparc官方的示例,官方示例可以說很全面、詳細了。

2、整合方式

1)增加Senparc配置節

appsettings.json中添加如下配置節:

 "SenparcSetting": {
    "IsDebug": true,
    "DefaultCacheNamespace": "Fuck"
    //分散式緩存
    //"Cache_Redis_Configuration": "#{Cache_Redis_Configuration}#", 
    //"Cache_Memcached_Configuration": "#{Cache_Memcached_Configuration}#", 
    //"SenparcUnionAgentKey": "#{SenparcUnionAgentKey}#" 
  },
  "SenparcWeixinSetting": {
    "IsDebug": true,
    "Token": "Fuck",
    "EncodingAESKey": "FuckKey",
    "WeixinAppId": "FuckAppId",
    "WeixinAppSecret": "FuckAppSecret"
  },

SenparcSetting部分是Senparc底層的通用配置,目前我項目中暫未用到,如果用到則對應配置,如緩存的命名空間,用來防止多應用可能的緩存key衝突,分散式緩存連接等。

SenparcWeixinSetting是公眾號相關的配置,Token、EncodingAESKey、WeixinAppId、WeixinAppSecret均分別對應公眾號後臺的賬戶信息,不多贅述。生產環境中,記得把上述IsDebug配置為false,減少調試信息及提高性能。

2) 微信消息處理器

  增加自定義消息處理器,繼承至MessageHandler<DefaultMpMessageContext>:

public class CustomMessageHandler : MessageHandler<DefaultMpMessageContext>
    {
        public CustomMessageHandler(Stream inputStream, PostModel postModel, int maxRecordCount = 0, bool onlyAllowEcryptMessage = false)
            : base(inputStream, postModel, maxRecordCount, onlyAllowEcryptMessage)
        {
            OnlyAllowEcryptMessage = true;
            //在指定條件下,不使用消息去重
            base.OmitRepeatedMessageFunc = requestMessage =>
            {
                var textRequestMessage = requestMessage as RequestMessageText;
                if (textRequestMessage != null && textRequestMessage.Content == "容錯")
                {
                    return false;
                }
                return true;
            };
        }

        public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
        {
            var responseMessage = this.CreateResponseMessage<ResponseMessageText>();
            responseMessage.Content = "您好,歡迎關註XXXX!";

            return responseMessage;
        }
    }

  

  重寫的DefaultResponseMessage方法表示,系統收到微信用戶收到的任何消息時,都自動回覆"您好,歡迎關註XXXX!"的文本消息。MessageHandler<DefaultMpMessageContext>中可以重載的方法很多,主要是響應微信終端動作的一系列方法,比如用戶發送文本、用戶點擊鏈接、用戶發送圖片、發送位置等,如果你需要處理對應事件,那就重載對應方法,我這裡偷懶了,搞了個所有類型消息預設回覆。

3)系統與微信通信

  增加控制器,如下:

    [AllowAnonymous]
    public class WeixinController : Controller
    {
        private readonly IWebHostEnvironment _env;
        private readonly SenparcWeixinSetting _weixinSetting;

        public WeixinController(IWebHostEnvironment env,
            IOptions<SenparcWeixinSetting> weixinSetting)
        {
            _env = env;
            _weixinSetting = weixinSetting.Value;
        }

        [HttpGet]
        [ActionName("Index")]
        public Task<ActionResult> Get(string signature, string timestamp, string nonce, string echostr)
        {
            return Task.Factory.StartNew(() =>
            {
                if (CheckSignature.Check(signature, timestamp, nonce, _weixinSetting.Token))
                {
                    return echostr; //返回隨機字元串則表示驗證通過
                }
                else
                {
                    return $"failed:{signature},{CheckSignature.GetSignature(timestamp, nonce, _weixinSetting.Token)}。如果你在瀏覽器中看到這句話,說明此地址可以被作為微信公眾賬號後臺的Url,請註意保持Token一致。";
                }
            })
                .ContinueWith<ActionResult>(task => Content(task.Result));
        }

        /// <summary>
        /// 最簡化的處理流程
        /// </summary>
        [HttpPost]
        [ActionName("Index")]
        public async Task<ActionResult> Post(PostModel postModel)
        {
            if (!CheckSignature.Check(postModel.Signature, postModel.Timestamp, postModel.Nonce, _weixinSetting.Token))
            {
                return new WeixinResult("參數錯誤!");
            }

            postModel.Token = _weixinSetting.Token;
            postModel.EncodingAESKey = _weixinSetting.EncodingAESKey;
            postModel.AppId = _weixinSetting.WeixinAppId;

            var cancellationToken = new CancellationToken();

            var messageHandler = new CustomMessageHandler(Request.GetRequestMemoryStream(), postModel, 10)
            {
                DefaultMessageHandlerAsyncEvent = DefaultMessageHandlerAsyncEvent.SelfSynicMethod
            };
            messageHandler.GlobalMessageContext.ExpireMinutes = 3;

            //messageHandler.SaveRequestMessageLog();
            await messageHandler.ExecuteAsync(cancellationToken);
            //messageHandler.SaveResponseMessageLog();

            return new FixWeixinBugWeixinResult(messageHandler);
        }

        [HttpPost]
        public ActionResult CreateMenu()
        {
            var menuFileInfo = _env.ContentRootFileProvider.GetFileInfo("menu.json");
            using (var stream = menuFileInfo.CreateReadStream())
            {
                using (StreamReader streamReader = new StreamReader(stream))
                {
                    var menuContent = streamReader.ReadToEnd();
                    MenuFull_ButtonGroup buttonGroup = JsonSerializer.Deserialize<MenuFull_ButtonGroup>(menuContent);

                    var tokenResult = Senparc.Weixin.MP.CommonAPIs.CommonApi.GetToken(_weixinSetting.WeixinAppId, _weixinSetting.WeixinAppSecret);
                    if (tokenResult.errcode != ReturnCode.請求成功)
                    {
                        return Json(tokenResult);
                    }

                    var menuResult = Senparc.Weixin.MP.CommonAPIs.CommonApi.CreateMenu(tokenResult.access_token, buttonGroup);
                    if (menuResult.errcode != ReturnCode.請求成功)
                    {
                        return Json(menuResult);
                    }

                    return Json("設置成功");
                }
            }
        }

        /// <summary>
        /// 獲取菜單介面
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public ActionResult GetMenu()
        {
            var tokenResult = Senparc.Weixin.MP.CommonAPIs.CommonApi.GetToken(_weixinSetting.WeixinAppId, _weixinSetting.WeixinAppSecret);
            if (tokenResult.errcode != ReturnCode.請求成功)
            {
                return Json(tokenResult);
            }

            var menuResult = Senparc.Weixin.MP.CommonAPIs.CommonApi.GetMenu(tokenResult.access_token);

            return Json(menuResult);
        }
    }

  構造函數中,註入微信相關配置SenparcWeixinSetting,get方法,用來響應微信官方的URL校驗,註意該方法公佈出去的reset地址需要跟公眾號後臺配置的token校驗地址一致。關於微信的token校驗,相比前幾年的一個變化是,開發者需要在功能變數名稱對應根路徑下放置一個微信後臺提供下載的TXT文件,聽起來繞是吧,那我往簡單說,就是http://yourdomain/xxxx.txt需要能訪問到公眾號後臺下載的那個xxxx.txt。可以根據具體部署情況靈活處理此要求,比如可以在反向代理層,也可以在應用中去處理,比如我這兒就是直接放在系統應用中處理,具體來說,如果在core中引用了UseStaticfile中間件,則core預設把wwwroot作為功能變數名稱根目錄公佈出去,我們的前端文件就是這麼被公佈出去的,所以在開啟Staticfile的情況下,直接把XXXX.txt文件放置到wwwroot目錄中即可通過微信文件校驗。說句題外話,微信這種校驗方式,其實和Let's encrypt數字證書的校驗是一樣的,目的就是為了證明你確實是你聲明的那個功能變數名稱對應的伺服器。

  Post方法,用來接收微信伺服器推送過來的微信終端的消息,其中就用到了上述自定義消息處理器。

  CreateMenu用來提供創建微信菜單的api,我的做法是把微信菜單定義在menu.json中,然後代碼讀取並調用微信相關方法創建。之所以這樣是因為菜單功能可能經常變化,所以做成配置化。生產環境中,記得給CreateMenu方法做鑒權,否則別人隨便操你的菜單,那可不是好玩兒的。

  GetMenu,獲取當前微信菜單,這個不必多說。

4)微信相關服務&中間件註冊

Startup.ConfigService中添加如下片段:

 //微信相關服務
            services.AddSenparcGlobalServices(Configuration)
                    .AddSenparcWeixinServices(Configuration);  

  這是註冊Senparc微信相關服務

Startup.Config中添加如下片段註冊Senparc相關中間件:

 IRegisterService register = RegisterService.Start(env, senparcSetting.Value)
                                                       .UseSenparcGlobal();
            register.RegisterTraceLog(() => ConfigTraceLog(monitorService));
            register.UseSenparcWeixin(senparcWeixinSetting.Value, senparcSetting.Value)  
                .RegisterMpAccount(senparcWeixinSetting.Value, "Fuck XXXXXX");

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 十大經典排序演算法 為了方便大家查找,我這裡弄一個偽目錄。 選擇排序 插入排序 冒泡排序 非優化版本 優化版本 希爾排序 歸併排序 遞歸式歸併排序 非遞歸式歸併排序 快速排序 堆排序 基數排序 非優化版本 優化版本 桶排序 基數排序 java編寫較好鏈接https://www.cnblogs.com/ ...
  • 28.模塊當腳本執行 !!!! 註意 這是分兩個文件的 一個是student.py和app3.py student.py name = "Song Ke" name_list = ["張三", "李四", "王五"] def who_am_i(myName): print(f'my name is ...
  • MATLAB實例:求相關係數、繪製熱圖並找到強相關對 作者:凱魯嘎吉 - 博客園 http://www.cnblogs.com/kailugaji/ 用MATLAB編程,求給定數據不同維度之間的相關係數,並繪製熱圖,保存圖片,找到強相關的維度對。 數據集來自UCI中的wine:https://arc ...
  • 來源:濟南小老虎 .NET Core是一個開源通用的開發框架,具有跨平臺能力,我們在享受其性能飆升的同時,也面臨了一些問題。通過觀察 NetCore 程式的線上運行情況發現 ,負載高的情況下應用程式占用記憶體較大,本文將針對這個問題展開討論,對比分析不同GC工作模式下的.NetCore性能與記憶體管理的 ...
  • 一、Asp.net Core基礎 微軟中文官網:https://docs.microsoft.com/zh-cn/aspnet/core/getting-started/ 微軟英文官網:https://docs.microsoft.com/en-us/aspnet/core/ .NET Core:h ...
  • 如下圖,如何判斷幾何多邊形A被多邊形B,切割為多段幾何? 幾何A被幾何B切割 1. 獲取幾何A與幾何B的交集C var intersectGeometry = new CombinedGeometry(GeometryCombineMode.Intersect, geometry1, geometr ...
  • 本篇只是從應用角度來說明asp.net core的選項模式,下一篇會從源碼來分析 1、以前的方式 以前我們使用web.config/app.config時是這樣使用配置的 寫["key"]操作麻煩,弱類型的還得自己轉,後來有人做了封裝 稍微好了點,全能方式,系統任何地方都可以調用,但是沒有組織,最好 ...
  • 相信看了我上一篇文章的小伙伴們都知道console這個類的最基本的2個方法了吧,下去練習過的小伙伴應該能知道4個方法。 那麼下麵我們就來介紹一下上期沒有介紹完的另外2個方法Console.WriteLine()和Console.ReadLine()這兩個方法和上一節我們學的Console.Write ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...