第八灵感 發表於 2021-5-14 22:19:00

1个类,2个方法,3句代码,完成微信公众号开发的极简流程

<h2>概述</h2>
<p>  Senparc.Weixin SDK 是一直以来大部分 .NET 微信开发者的首选微信 SDK(以下统称 SDK),SDK 目前已经支持了微信公众号、小程序、企业微信、微信支付等绝大部分微信接口,为庞大的微信生态应用提供支撑。</p>
<p>  随着微信官方接口的不断丰富和更新,Sample&nbsp;变得日益庞大,可以说“0基础”去看目前 SDK Sample 是需要一些耐心的(当然这非常非常值得)。以至于也看到有开发者一见 Sample,就会误以为 SDK 是一个很“重”的框架。</p>
<p>  其实不然,下面我将以最简洁的代码:在全新 ASP.NET Core 项目里,只新建 1 个类、创建 2 个方法、添加 3 句代码,就能完成公众号的消息回复以及高级接口调用的演示,如果你已经使用过 SDK,整个过程只需要 5 分钟。如果你还没有接触过微信开发,那么请你留出 15 分钟,瞬间“入门”微信开发,这将是一次性价比极高的探索!</p>
<p>&nbsp;</p>
<h2>开始开发</h2>
<blockquote>
<p><strong>开发目标:在新的 ASP.NET Core 项目中,实现微信公众号消息的回复,并调用高级接口</strong></p>
</blockquote>
<p>&nbsp;</p>
<p><strong>  第一步:新建 ASP.NET Core 项目</strong></p>
<p style="text-align: center">&nbsp;<img src="https://img2020.cnblogs.com/blog/28384/202105/28384-20210514172743561-1016388040.png" alt="" width="720" height="478" loading="lazy"></p>
<p style="text-align: center">选择代码最简单的【ASP.NET Core 空】项目模板</p>
<p style="text-align: center">&nbsp;</p>
<p style="text-align: center"><img src="https://img2020.cnblogs.com/blog/28384/202105/28384-20210514172850095-793135866.png" alt="" width="723" height="480" loading="lazy"></p>
<p style="text-align: center">&nbsp;设置项目名称和路径</p>
<p style="text-align: center">&nbsp;</p>
<p style="text-align: center"><img src="https://img2020.cnblogs.com/blog/28384/202105/28384-20210514172956244-287228642.png" alt="" width="726" height="482" loading="lazy"></p>
<p style="text-align: center">选择.NET 6,也可以选择其他版本&nbsp;</p>
<p>&nbsp;</p>
<p style="text-align: center"><img src="https://img2020.cnblogs.com/blog/28384/202105/28384-20210514174542160-218314315.png" alt="" loading="lazy"></p>
<p style="text-align: center">创建完成</p>
<p>&nbsp;</p>
<p>  安装 Nuget 包:Senparc.Weixin.MP(对应公众号)、Senparc.Weixin.MP.Middleware(对应公众号消息中间件)。</p>
<p>  PS:由于后者依赖前者,也可以只装&nbsp;Senparc.Weixin.MP.Middleware。</p>
<p style="text-align: center"><br><img src="https://img2020.cnblogs.com/blog/28384/202105/28384-20210514174705492-1370371105.png" alt="" width="609" height="754" loading="lazy"></p>
<p style="text-align: center">&nbsp;打开【管理 Nuget 工具包】窗口</p>
<p style="text-align: center">&nbsp;</p>
<p style="text-align: center"><img src="https://img2020.cnblogs.com/blog/28384/202105/28384-20210514181503512-38241890.png" alt="" width="903" height="582" loading="lazy"></p>
<p style="text-align: center">安装&nbsp;Senparc.Weixin.MP(本案例中可选)、Senparc.Weixin.MP.Middleware(本案例中必须)</p>
<p>&nbsp;  默认的 startup.cs 文件,稍作修改,加入更多的依赖注入参数:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span>   <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)"> Startup
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span> <span style="color: rgba(0, 0, 0, 1)">    {
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>         <span style="color: rgba(0, 0, 255, 1)">public</span><span style="color: rgba(0, 0, 0, 1)"> Startup(<span style="color: rgba(255, 0, 0, 1)">IConfiguration configuration</span>)
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span> <span style="color: rgba(0, 0, 0, 1)">      {
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span>             <span style="color: rgba(255, 0, 0, 1)">Configuration = configuration;
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span>         <span style="color: rgba(255, 0, 0, 1)">public IConfiguration Configuration { get; }
</span><span style="color: rgba(0, 128, 128, 1)"> 9</span>
<span style="color: rgba(0, 128, 128, 1)">10</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> ConfigureServices(IServiceCollection services)
</span><span style="color: rgba(0, 128, 128, 1)">11</span> <span style="color: rgba(0, 0, 0, 1)">      {
</span><span style="color: rgba(0, 128, 128, 1)">12</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">13</span>
<span style="color: rgba(0, 128, 128, 1)">14</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Configure(IApplicationBuilder app, IWebHostEnvironment env,
</span><span style="color: rgba(0, 128, 128, 1)">15</span>               <span style="color: rgba(255, 0, 0, 1)">IOptions&lt;SenparcSetting&gt; senparcSetting, IOptions&lt;SenparcWeixinSetting&gt;</span><span style="color: rgba(0, 0, 0, 1)"><span style="color: rgba(255, 0, 0, 1)"> senparcWeixinSetting</span>)
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)">      {
</span><span style="color: rgba(0, 128, 128, 1)">17</span>             <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (env.IsDevelopment())
</span><span style="color: rgba(0, 128, 128, 1)">18</span> <span style="color: rgba(0, 0, 0, 1)">            {
</span><span style="color: rgba(0, 128, 128, 1)">19</span> <span style="color: rgba(0, 0, 0, 1)">                app.UseDeveloperExceptionPage();
</span><span style="color: rgba(0, 128, 128, 1)">20</span> <span style="color: rgba(0, 0, 0, 1)">            }
</span><span style="color: rgba(0, 128, 128, 1)">21</span>
<span style="color: rgba(0, 128, 128, 1)">22</span> <span style="color: rgba(0, 0, 0, 1)">            app.UseRouting();
</span><span style="color: rgba(0, 128, 128, 1)">23</span>
<span style="color: rgba(0, 128, 128, 1)">24</span>             app.UseEndpoints(endpoints =&gt;
<span style="color: rgba(0, 128, 128, 1)">25</span> <span style="color: rgba(0, 0, 0, 1)">            {
</span><span style="color: rgba(0, 128, 128, 1)">26</span>               endpoints.MapGet(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">async</span> context =&gt;
<span style="color: rgba(0, 128, 128, 1)">27</span> <span style="color: rgba(0, 0, 0, 1)">                {
</span><span style="color: rgba(0, 128, 128, 1)">28</span>                     <span style="color: rgba(0, 0, 255, 1)">await</span> context.Response.WriteAsync(<span style="color: rgba(128, 0, 0, 1)">"Hello Senparc!</span><span style="color: rgba(128, 0, 0, 1)">"</span>);
<span style="color: rgba(0, 128, 128, 1)">29</span> <span style="color: rgba(0, 0, 0, 1)">                });
</span><span style="color: rgba(0, 128, 128, 1)">30</span> <span style="color: rgba(0, 0, 0, 1)">            });
</span><span style="color: rgba(0, 128, 128, 1)">31</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">32</span>   }</pre>
</div>
<p>  上述标红的代码为新增的代码。</p>
<p>  至此项目创建完成,下面将开始我们的极简 Sample 创建之旅。</p>
<p>&nbsp;</p>
<p><strong>  第二步:创建 CustomMessageHandler 类(1个类)</strong></p>
<p>&nbsp;  CustomMessageHandler 是处理用户发送到微信公众号的消息的统一事务中心,为了方便查看,CustomMessageHandler 直接添加在 startup.cs 中:</p>
<div class="cnblogs_code">
<pre>    <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
    <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 自定义消息处理器
    </span><span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">class</span> CustomMessageHandler : MessageHandler&lt;DefaultMpMessageContext&gt;<span style="color: rgba(0, 0, 0, 1)">
    {
      </span><span style="color: rgba(0, 0, 255, 1)">public</span> CustomMessageHandler(Stream inputStream, PostModel postModel, <span style="color: rgba(0, 0, 255, 1)">int</span> maxRecordCount = <span style="color: rgba(128, 0, 128, 1)">0</span>, IServiceProvider serviceProvider = <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">)
            : </span><span style="color: rgba(0, 0, 255, 1)">base</span>(inputStream, postModel, maxRecordCount, <span style="color: rgba(0, 0, 255, 1)">false</span>, <span style="color: rgba(0, 0, 255, 1)">null</span><span style="color: rgba(0, 0, 0, 1)">, serviceProvider)
      {
      }
    }</span></pre>
</div>
<p>&nbsp;</p>
<p><strong>  第三步:配置回复消息并调用高级接口(2个方法)</strong></p>
<p>  在 CustomMessageHandler 内添加2个方法,分别处理用户发送过来的文字消息,以及还没有进行自定义的其他消息类型:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span>         <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 2</span>         <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 回复以文字形式发送的信息(可选)
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span>         <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)"> 4</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span> <span style="color: rgba(0, 0, 255, 1)">async</span> Task&lt;IResponseMessageBase&gt;<span style="color: rgba(0, 0, 0, 1)"> OnTextOrEventRequestAsync(RequestMessageText requestMessage)
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">      {
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span>             <span style="color: rgba(0, 0, 255, 1)">var</span> responseMessage = <span style="color: rgba(0, 0, 255, 1)">base</span>.CreateResponseMessage&lt;ResponseMessageText&gt;<span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span>             <span style="color: rgba(0, 0, 255, 1)">await</span> MP.AdvancedAPIs.CustomApi.SendTextAsync(Config.SenparcWeixinSetting.MpSetting.WeixinAppId, OpenId, $<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">这是一条异步的客服消息</span><span style="color: rgba(128, 0, 0, 1)">"</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">注意:只有测试号或部署到正式环境的正式服务号可用此接口</span>
<span style="color: rgba(0, 128, 128, 1)"> 8</span>             responseMessage.Content = $<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">你发送了文字:{requestMessage.Content}\r\n\r\n你的OpenId:{OpenId}</span><span style="color: rgba(128, 0, 0, 1)">"</span>;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">以文字类型消息回复</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span>             <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> responseMessage;
</span><span style="color: rgba(0, 128, 128, 1)">10</span> <span style="color: rgba(0, 0, 0, 1)">      }
</span><span style="color: rgba(0, 128, 128, 1)">11</span>
<span style="color: rgba(0, 128, 128, 1)">12</span>         <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)">13</span>         <span style="color: rgba(128, 128, 128, 1)">///</span><span style="color: rgba(0, 128, 0, 1)"> 默认消息
</span><span style="color: rgba(0, 128, 128, 1)">14</span>         <span style="color: rgba(128, 128, 128, 1)">///</span> <span style="color: rgba(128, 128, 128, 1)">&lt;/summary&gt;</span>
<span style="color: rgba(0, 128, 128, 1)">15</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">override</span><span style="color: rgba(0, 0, 0, 1)"> IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)
</span><span style="color: rgba(0, 128, 128, 1)">16</span> <span style="color: rgba(0, 0, 0, 1)">      {
</span><span style="color: rgba(0, 128, 128, 1)">17</span>             <span style="color: rgba(0, 0, 255, 1)">var</span> responseMessage = <span style="color: rgba(0, 0, 255, 1)">base</span>.CreateResponseMessage&lt;ResponseMessageText&gt;<span style="color: rgba(0, 0, 0, 1)">();
</span><span style="color: rgba(0, 128, 128, 1)">18</span>             responseMessage.Content = $<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">欢迎来到我的公众号!当前时间:{SystemTime.Now}</span><span style="color: rgba(128, 0, 0, 1)">"</span>;<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">没有自定义的消息统一回复固定消息</span>
<span style="color: rgba(0, 128, 128, 1)">19</span>             <span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> responseMessage;
</span><span style="color: rgba(0, 128, 128, 1)">20</span>         }</pre>
</div>
<p>&nbsp;</p>
<p><strong>  第四步:添加注册和配置代码(3句代码)</strong></p>
<blockquote>
<p><strong>说明:</strong>3 句代码都只需要在 Startup.cs 中加入,因此整个过程不需要动用或者新建任何其他文件。</p>
</blockquote>
<p>    第 1 句:注册缓存和 Senparc 微信服务:</p>
<div class="cnblogs_code">
<pre>      <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> ConfigureServices(IServiceCollection services)
      {
<span style="color: rgba(255, 0, 0, 1)">            services.AddMemoryCache()</span></span><span style="color: rgba(255, 0, 0, 1)">//使用本地缓存必须添加
                  .AddSenparcWeixinServices(Configuration);//Senparc.Weixin 注册(必须)</span>
      }</pre>
</div>
<p>    第 2 句:注册 Senparc.Weixin 及基础库;</p>
<p>    第 3 句:使用消息中间件注册 CustomMessageHandler:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 128, 128, 1)"> 1</span>         <span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">void</span><span style="color: rgba(0, 0, 0, 1)"> Configure(IApplicationBuilder app, IWebHostEnvironment env,
</span><span style="color: rgba(0, 128, 128, 1)"> 2</span>               IOptions&lt;SenparcSetting&gt; senparcSetting, IOptions&lt;SenparcWeixinSetting&gt;<span style="color: rgba(0, 0, 0, 1)"> senparcWeixinSetting)
</span><span style="color: rgba(0, 128, 128, 1)"> 3</span> <span style="color: rgba(0, 0, 0, 1)">      {
</span><span style="color: rgba(0, 128, 128, 1)"> 4</span>             <span style="color: rgba(0, 0, 255, 1)">if</span><span style="color: rgba(0, 0, 0, 1)"> (env.IsDevelopment())
</span><span style="color: rgba(0, 128, 128, 1)"> 5</span> <span style="color: rgba(0, 0, 0, 1)">            {
</span><span style="color: rgba(0, 128, 128, 1)"> 6</span> <span style="color: rgba(0, 0, 0, 1)">                app.UseDeveloperExceptionPage();
</span><span style="color: rgba(0, 128, 128, 1)"> 7</span> <span style="color: rgba(0, 0, 0, 1)">            }
</span><span style="color: rgba(0, 128, 128, 1)"> 8</span>
<span style="color: rgba(0, 128, 128, 1)"> 9</span>             <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">注册 Senparc.Weixin 及基础库</span>
<span style="color: rgba(255, 0, 0, 1)">10             var registerService = app.UseSenparcGlobal(env, senparcSetting.Value, _ =&gt; { }, true)
11                                    .UseSenparcWeixin(senparcWeixinSetting.Value, weixinRegister =&gt; weixinRegister.RegisterMpAccount(senparcWeixinSetting.Value));
</span><span style="color: rgba(0, 128, 128, 1)">12</span>
<span style="color: rgba(0, 128, 128, 1)">13</span> <span style="color: rgba(0, 0, 0, 1)">            app.UseRouting();
</span><span style="color: rgba(0, 128, 128, 1)">14</span>
<span style="color: rgba(0, 128, 128, 1)">15</span>             <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">使用中间件注册 MessageHandler,指定 CustomMessageHandler 为自定义处理方法</span>
<span style="color: rgba(255, 0, 0, 1)">16             app.UseMessageHandlerForMp("<strong>/WeixinAsync</strong>",
17               (stream, postModel, maxRecordCount, serviceProvider) =&gt; new CustomMessageHandler(stream, postModel, maxRecordCount, serviceProvider),
18               options =&gt;
19               {
20                     options.AccountSettingFunc = context =&gt; senparcWeixinSetting.Value;
21               });
</span><span style="color: rgba(0, 128, 128, 1)">22</span>
<span style="color: rgba(0, 128, 128, 1)">23</span>             app.UseEndpoints(endpoints =&gt;
<span style="color: rgba(0, 128, 128, 1)">24</span> <span style="color: rgba(0, 0, 0, 1)">            {
</span><span style="color: rgba(0, 128, 128, 1)">25</span>               endpoints.MapGet(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">/</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(0, 0, 255, 1)">async</span> context =&gt;
<span style="color: rgba(0, 128, 128, 1)">26</span> <span style="color: rgba(0, 0, 0, 1)">                {
</span><span style="color: rgba(0, 128, 128, 1)">27</span>                     <span style="color: rgba(0, 0, 255, 1)">await</span> context.Response.WriteAsync(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Open /WeixinAsync to connect WeChat MessageHandler</span><span style="color: rgba(128, 0, 0, 1)">"</span>);<span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">首页默认显示</span>
<span style="color: rgba(0, 128, 128, 1)">28</span> <span style="color: rgba(0, 0, 0, 1)">                });
</span><span style="color: rgba(0, 128, 128, 1)">29</span> <span style="color: rgba(0, 0, 0, 1)">            });
</span><span style="color: rgba(0, 128, 128, 1)">30</span>         }</pre>
</div>
<p>  其中,<strong>/WeixinAsync&nbsp;</strong>是可以自定义的消息 URL 路径。</p>
<p>&nbsp;</p>
<p><strong>  第五步:配对微信账号信息</strong></p>
<p>  微信公众号的配置都可以统一在 appsettings.json 中配置,只需要添加 2 个节点信息,修改如下:</p>
<div class="cnblogs_code">
<pre><span style="color: rgba(0, 0, 0, 1)">{
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Logging</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">LogLevel</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
      </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Default</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Information</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Microsoft</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Warning</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
      </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Microsoft.Hosting.Lifetime</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Information</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
    }
},
</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">AllowedHosts</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">*</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,

</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">CO2NET 设置</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">SenparcSetting</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">IsDebug</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">DefaultCacheNamespace</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">DefaultCache</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
},
</span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Senparc.Weixin SDK 设置</span>
<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">SenparcWeixinSetting</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">: {
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">IsDebug</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(0, 0, 255, 1)">true</span><span style="color: rgba(0, 0, 0, 1)">,

    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">Token</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">YourToken</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">EncodingAESKey</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">EncodingAESKey</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">WeixinAppId</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">YourAppId</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">,
    </span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">WeixinAppSecret</span><span style="color: rgba(128, 0, 0, 1)">"</span>: <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">YourAppSecret</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">
}
}</span></pre>
</div>
<p>&nbsp;</p>
<p><strong>  完成。</strong></p>
<p>&nbsp;&nbsp;</p>
<h2>运行</h2>
<p>  直接运行当前项目,即可打开首页:</p>
<p style="text-align: center"><img src="https://img2020.cnblogs.com/blog/28384/202105/28384-20210514184426361-1940352366.png" alt="" width="764" height="407" loading="lazy"></p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;  按照提示,打开 路径 <strong>/WeixinAsync</strong>,即可看到测试成功信息:</p>
<p><img src="https://img2020.cnblogs.com/blog/28384/202105/28384-20210514184612494-1789761587.png" alt="" width="1073" height="850" loading="lazy" style="display: block; margin-left: auto; margin-right: auto"></p>
<p>&nbsp;&nbsp;</p>
<h2>测试</h2>
<p>&nbsp;  将程序部署至公网(<span style="color: rgba(255, 0, 0, 1)">或在本地进行简单的配置*</span>)后,在公众号后台配置 URL、Token等信息,即可轻松获得所有验证、消息对接的能力。当我们发送消息时,如下所示:</p>
<p style="text-align: center"><img src="https://img2020.cnblogs.com/blog/28384/202105/28384-20210514212047088-496535502.jpg" alt="" width="459" height="994" loading="lazy"></p>
<p style="text-align: center">&nbsp;</p>
<h2 style="text-align: center"><span style="color: rgba(255, 0, 0, 1)">*那么问题来了:我没有服务器,也没有注册微信公众号,如何在本地完成以上所有上线操作和测试呢?</span></h2>
<p style="text-align: center">——请看下一篇:《在开发环境内网穿透测试微信公众号》。</p>
<p>&nbsp;</p>
<h2>&nbsp;源码</h2>
<p>&nbsp;  本文代码已经上传至</p>
<p>  GitHub:https://github.com/JeffreySu/Senparc.Weixin.Samples/tree/main/Senparc.Weixin.Sample.Net6.MinSample</p>
<p>  Gitee:https://gitee.com/JeffreySu/Senparc.Weixin.Samples/tree/main/Senparc.Weixin.Sample.Net6.MinSample</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h2>更多微信开发教程:</h2>
<ol><ol>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(一):微信公众平台注册</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(二):成为开发者</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(三):微信公众平台开发验证</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(四):Hello World</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(五):使用Senparc.Weixin.MP SDK</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(六):了解MessageHandler</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(七):解决用户上下文(Session)问题</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(八):通用接口说明</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(九):自定义菜单接口说明</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(十):多客服接口说明</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(十一):高级接口说明</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(十二):OAuth2.0说明</li>
<li>Senparc.Weixin.MP SDK&nbsp;微信公众平台开发教程(十三):地图相关接口说明</li>
<li>Senparc.Weixin.MP SDK 微信公众平台开发教程(十四):请求消息去重</li>
<li>Senparc.Weixin.MP SDK 微信公众平台开发教程(十五):消息加密</li>
<li>Senparc.Weixin.MP SDK 微信公众平台开发教程(十六):AccessToken自动管理机制</li>
<li>Senparc.Weixin.MP SDK 微信公众平台开发教程(十七):个性化菜单接口说明</li>
<li>Senparc.Weixin.MP SDK 微信公众平台开发教程(十八):Web代理功能</li>
<li>Senparc.Weixin.MP SDK 微信公众平台开发教程(十九):MessageHandler 的未知类型消息处理</li>
<li>Senparc.Weixin.MP SDK 微信公众平台开发教程(二十):使用菜单消息功能</li>
<li>Senparc.Weixin.MP SDK 微信公众平台开发教程(二十一):在小程序中使用 WebSocket (.NET Core)</li>
<li>Senparc.Weixin.MP SDK 微信公众平台开发教程(二十二):如何安装 Nuget(dll) 后使用项目源代码调试</li>
</ol></ol>

</div>
<div id="MySignature" role="contentinfo">
    <p>&nbsp;</p>

<p>
转载请注明出处和作者,谢谢!<br>
作者:JeffreySu/https://github.com/JeffreySu/<br>
博客:https://szw.cnblogs.com/<br>
</p>

<!--
<p>&nbsp;</p>
<p>
Senparc官方教程《微信开发深度解析:微信公众号、小程序高效开发秘籍》,耗时2年精心打造的微信开发权威教程,点击这里,购买正版!<br>
<img src="https://images2017.cnblogs.com/blog/28384/201707/28384-20170730224601537-1461862917.png" width="300" alt="
微信开发深度解析:微信公众号、小程序高效开发秘籍"><br>

</p>
<p>&nbsp;</p>


<div style="margin-bottom: 30px">
Senparc 官方微信开发视频教程:《微信公众号+小程序快速开发》,点击这里点击观看。<br>

<img src="https://images2017.cnblogs.com/blog/28384/201802/28384-20180208161432998-278885671.png" width="300" alt="Senparc 官方微信开发视频教程:《微信公众号+小程序快速开发》">

</div>--><br><br>
来源:https://www.cnblogs.com/szw/p/wecaht-minimization-example.html
頁: [1]
查看完整版本: 1个类,2个方法,3句代码,完成微信公众号开发的极简流程