<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>微信公众平台开发ASP.NET Core MVC2版本 &#8211; FoxDevelop</title>
	<atom:link href="https://www.foxdevelop.com/zh/category/%E5%BE%AE%E4%BF%A1%E5%85%AC%E4%BC%97%E5%B9%B3%E5%8F%B0%E5%BC%80%E5%8F%91asp-net-core-mvc2%E7%89%88%E6%9C%AC/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.foxdevelop.com</link>
	<description>独立软件开发工作室</description>
	<lastBuildDate>Mon, 28 Sep 2026 01:23:58 +0000</lastBuildDate>
	<language>zh-Hans</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.1.2</generator>

<image>
	<url>https://www.foxdevelop.com/wp-content/uploads/2026/05/fox-svgrepo-com-1.png</url>
	<title>微信公众平台开发ASP.NET Core MVC2版本 &#8211; FoxDevelop</title>
	<link>https://www.foxdevelop.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>18-非微信服务器推送给我们系统的消息可以本地local域名来测试</title>
		<link>https://www.foxdevelop.com/zh/2026/09/28/18-%e9%9d%9e%e5%be%ae%e4%bf%a1%e6%9c%8d%e5%8a%a1%e5%99%a8%e6%8e%a8%e9%80%81%e7%bb%99%e6%88%91%e4%bb%ac%e7%b3%bb%e7%bb%9f%e7%9a%84%e6%b6%88%e6%81%af%e5%8f%af%e4%bb%a5%e6%9c%ac%e5%9c%b0local%e5%9f%9f/</link>
					<comments>https://www.foxdevelop.com/zh/2026/09/28/18-%e9%9d%9e%e5%be%ae%e4%bf%a1%e6%9c%8d%e5%8a%a1%e5%99%a8%e6%8e%a8%e9%80%81%e7%bb%99%e6%88%91%e4%bb%ac%e7%b3%bb%e7%bb%9f%e7%9a%84%e6%b6%88%e6%81%af%e5%8f%af%e4%bb%a5%e6%9c%ac%e5%9c%b0local%e5%9f%9f/#respond</comments>
		
		<dc:creator><![CDATA[jack]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 01:23:58 +0000</pubDate>
				<category><![CDATA[微信公众平台开发ASP.NET Core MVC2版本]]></category>
		<guid isPermaLink="false">https://www.foxdevelop.com/?p=13073</guid>

					<description><![CDATA[本地调试微信公众号接口（非回调类） 你说得非常对，这里其实涉 ...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">本地调试微信公众号接口（非回调类）</h3>



<p class="wp-block-paragraph">你说得非常对，这里其实涉及两类接口，性质完全不同：</p>



<h4 class="wp-block-heading">一、需要域名（微信服务器主动推送）</h4>



<p class="wp-block-paragraph">这类接口是<strong>微信服务器向你的服务器发请求</strong>，所以你的程序必须能被外网访问：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>场景</th><th>说明</th></tr></thead><tbody><tr><td>接收用户消息</td><td>用户给公众号发文字、图片等</td></tr><tr><td>事件推送</td><td>关注/取消关注、菜单点击、扫码等</td></tr><tr><td>网页授权回调</td><td>用户授权后微信跳转回 <code>redirect_uri</code></td></tr></tbody></table></figure>



<p class="wp-block-paragraph">这些情况下微信服务器需要能访问到你的 URL，所以必须配置：</p>



<ul class="wp-block-list">
<li>外网域名（如 <code>2l1941590s.imwork.net</code>）</li>



<li>或内网穿透工具（花生壳、ngrok、frp 等）</li>
</ul>



<p class="wp-block-paragraph">这也是为什么之前要在测试账号里配接口地址、配网页授权回调域名的原因。</p>



<h4 class="wp-block-heading">二、不需要域名（主动调用微信 API）</h4>



<p class="wp-block-paragraph">这类接口是<strong>你的服务器主动请求微信服务器</strong>，微信不会反向访问你，所以完全不需要外网可达：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>场景</th><th>接口</th></tr></thead><tbody><tr><td>获取 AccessToken</td><td><code>/cgi-bin/token</code></td></tr><tr><td>获取用户列表</td><td><code>/cgi-bin/user/get</code></td></tr><tr><td>获取用户信息</td><td><code>/cgi-bin/user/info</code></td></tr><tr><td>创建/删除菜单</td><td><code>/cgi-bin/menu/create</code></td></tr><tr><td>发送模板消息</td><td><code>/cgi-bin/message/template/send</code></td></tr><tr><td>设置行业</td><td><code>/cgi-bin/template/api_set_industry</code></td></tr><tr><td>获取模板列表</td><td><code>/cgi-bin/template/get_all_private_template</code></td></tr><tr><td>群发消息</td><td><code>/cgi-bin/message/mass/send</code></td></tr></tbody></table></figure>



<p class="wp-block-paragraph">这些接口本质上就是 HTTP POST/GET 请求微信的 API 服务器，跟你在浏览器里访问一个网址没区别。</p>



<h4 class="wp-block-heading">本地调试方式</h4>



<p class="wp-block-paragraph">所以你可以直接在本地用 <code>localhost</code> 或 <code>127.0.0.1</code> 跑项目，直接调用这些接口：</p>


<pre class="wp-block-code"><span><code class="hljs language-php"><span class="hljs-comment">// 本地直接调试，不需要域名</span>
<span class="hljs-keyword">public</span> ActionResult TestGetToken()
{
    <span class="hljs-keyword">var</span> token = GetAccessToken(); <span class="hljs-comment">// 缓存版，7200秒有效</span>
    <span class="hljs-keyword">return</span> Content(token);
}

<span class="hljs-keyword">public</span> ActionResult TestGetUserList()
{
    <span class="hljs-keyword">var</span> url = $<span class="hljs-string">"https://api.weixin.qq.com/cgi-bin/user/get?access_token={GetAccessToken()}"</span>;
    <span class="hljs-keyword">var</span> json = HtmlHelper.HttpGet(url);
    <span class="hljs-keyword">return</span> Content(json);
}

<span class="hljs-keyword">public</span> ActionResult TestCreateMenu()
{
    <span class="hljs-comment">// 创建菜单，本地直接发请求即可</span>
    <span class="hljs-keyword">var</span> handler = <span class="hljs-keyword">new</span> MenuCreateHandle();
    <span class="hljs-keyword">var</span> result = handler.DoPost&lt;dynamic&gt;();
    <span class="hljs-keyword">return</span> Json(result);
}</code></span></pre>


<p class="wp-block-paragraph">访问 <code>http://localhost:端口号/home/TestGetToken</code> 就能直接调通。</p>



<h4 class="wp-block-heading">实际开发建议</h4>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>场景</th><th>推荐做法</th></tr></thead><tbody><tr><td>开发阶段（主动调用API）</td><td>本地 localhost 直接调试，快速方便</td></tr><tr><td>开发阶段（接收消息/事件）</td><td>用内网穿透（花生壳/ngrok）映射到本地</td></tr><tr><td>测试/生产环境</td><td>部署到服务器，配真实域名</td></tr></tbody></table></figure>



<h4 class="wp-block-heading">调试技巧</h4>



<ol class="wp-block-list">
<li><strong>Token 缓存后本地调试更高效</strong>：配合上一节课的 <code>CacheOrLoad</code> 方法，Token 两小时内不重复请求，本地调试基本秒响应。</li>



<li><strong>用 Postman 也能直接测</strong>：这些 API 本质上就是 HTTPS 请求，拿到 access_token 后，Postman 里直接填参数就能调。</li>



<li><strong>区分两类接口写代码</strong>：可以把主动调用微信 API 的逻辑封装成 Service 类，不依赖 HttpContext，方便本地单元测试。</li>
</ol>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.foxdevelop.com/zh/2026/09/28/18-%e9%9d%9e%e5%be%ae%e4%bf%a1%e6%9c%8d%e5%8a%a1%e5%99%a8%e6%8e%a8%e9%80%81%e7%bb%99%e6%88%91%e4%bb%ac%e7%b3%bb%e7%bb%9f%e7%9a%84%e6%b6%88%e6%81%af%e5%8f%af%e4%bb%a5%e6%9c%ac%e5%9c%b0local%e5%9f%9f/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>17-Token使用缓存的方式来存储</title>
		<link>https://www.foxdevelop.com/zh/2026/09/28/17-token%e4%bd%bf%e7%94%a8%e7%bc%93%e5%ad%98%e7%9a%84%e6%96%b9%e5%bc%8f%e6%9d%a5%e5%ad%98%e5%82%a8/</link>
					<comments>https://www.foxdevelop.com/zh/2026/09/28/17-token%e4%bd%bf%e7%94%a8%e7%bc%93%e5%ad%98%e7%9a%84%e6%96%b9%e5%bc%8f%e6%9d%a5%e5%ad%98%e5%82%a8/#respond</comments>
		
		<dc:creator><![CDATA[jack]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 01:23:07 +0000</pubDate>
				<category><![CDATA[微信公众平台开发ASP.NET Core MVC2版本]]></category>
		<guid isPermaLink="false">https://www.foxdevelop.com/?p=13072</guid>

					<description><![CDATA[优化 Token 存储：使用绝对过期缓存 之前的项目中，每次 ...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">优化 Token 存储：使用绝对过期缓存</h3>



<p class="wp-block-paragraph">之前的项目中，每次都去微信服务器获取新的 AccessToken，这样肯定不好。微信服务器返回的 Token 有效期是 <strong>7200 秒（2 小时）</strong>，在这期间 Token 都是有效的，没必要每次都重新获取，频繁调用也会影响程序性能。</p>



<p class="wp-block-paragraph">我们可以通过 <strong>ASP.NET 缓存（Cache）</strong>​ 把第一次获取到的 Token 存起来，设置 <strong>绝对过期时间</strong>​ 为 7200 秒，到期自动失效，下次再重新获取。</p>



<h4 class="wp-block-heading">为什么用绝对过期而不是滑动过期？</h4>



<ul class="wp-block-list">
<li><strong>绝对过期（Absolute Expiration）</strong>：从加入缓存那一刻起，到指定时间点就过期，不管期间有没有被访问。正好契合微信 Token 的 7200 秒有效期。</li>



<li><strong>滑动过期（Sliding Expiration）</strong>：每次访问缓存就刷新过期时间，这会导致 Token 永远不过期，但微信服务器那边其实已经失效了，不能用。</li>
</ul>



<p class="wp-block-paragraph">所以这里使用 <code>System.Web.Caching.Cache.NoSlidingExpiration</code> 禁用滑动过期，配合 <code>DateTime.Now.AddSeconds(7200)</code> 实现绝对过期。</p>



<h4 class="wp-block-heading">缓存获取/加载通用方法</h4>


<pre class="wp-block-code"><span><code class="hljs language-php"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> object _lock = <span class="hljs-keyword">new</span> object();

<span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> T CacheOrLoad&lt;T&gt;(string key, Func&lt;T&gt; action)
{
    T token = <span class="hljs-keyword">default</span>(T);
    lock (_lock)
    {
        <span class="hljs-comment">// 1. 先从缓存里取</span>
        token = (T)System.Web.HttpRuntime.Cache.Get(key);
        <span class="hljs-keyword">if</span> (token == <span class="hljs-keyword">null</span>)
        {
            <span class="hljs-comment">// 2. 缓存里没有，调用委托去微信服务器获取新 token</span>
            token = action();
            <span class="hljs-comment">// 3. 加入缓存，绝对过期时间 7200 秒，非滑动过期</span>
            System.Web.HttpRuntime.Cache.Add(
                key,
                token,
                <span class="hljs-keyword">null</span>,
                DateTime.Now.AddSeconds(<span class="hljs-number">7200</span>),
                System.Web.Caching.Cache.NoSlidingExpiration,
                System.Web.Caching.CacheItemPriority.<span class="hljs-keyword">Default</span>,
                <span class="hljs-keyword">null</span>
            );
        }
    }
    <span class="hljs-keyword">return</span> token;
}</code></span></pre>


<h4 class="wp-block-heading">调用示例</h4>


<pre class="wp-block-code"><span><code class="hljs language-javascript">public <span class="hljs-keyword">static</span> string GetAccessToken()
{
    <span class="hljs-keyword">return</span> CacheOrLoad&lt;string&gt;<span class="hljs-function">(<span class="hljs-params"><span class="hljs-string">"Token_KEY"</span>, (</span>) =&gt;</span>
    {
        <span class="hljs-comment">// 这里实际请求微信服务器获取 token</span>
        <span class="hljs-comment">// 伪代码：return HttpGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&amp;appid=" + appid + "&amp;secret=" + secret);</span>
        <span class="hljs-keyword">return</span> <span class="hljs-string">"xxxdsfstirjflds;fjdsoifdslfdsf"</span>; <span class="hljs-comment">// 请求微信服务器获取token</span>
    });
}</code></span></pre>


<h4 class="wp-block-heading">控制台测试程序</h4>


<pre class="wp-block-code"><span><code class="hljs language-javascript"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> Main(string&#91;] args)
{
    <span class="hljs-keyword">var</span> result = CacheOrLoad(<span class="hljs-string">"Token_KEY"</span>, () =&gt;
    {
        <span class="hljs-keyword">return</span> <span class="hljs-string">"xxxdsfstirjflds;fjdsoifdslfdsf"</span>; <span class="hljs-comment">// 请求微信服务器获取token</span>
    });

    Console.WriteLine(result);
    Console.ReadKey();
}</code></span></pre>


<h4 class="wp-block-heading">应用到现有项目中的要点</h4>



<ol class="wp-block-list">
<li><strong>加锁</strong>：使用 <code>lock (_lock)</code> 防止并发时多个请求同时去微信服务器取 Token，避免短时间内多次调用接口被限频。</li>



<li><strong>缓存键唯一</strong>：不同公众号、不同用途的 Token 用不同的 key，比如 <code>"Token_KEY"</code>、<code>"WebAccessToken_KEY"</code> 等。</li>



<li><strong>异常处理</strong>：如果获取 Token 失败（网络异常、appid/secret 错误），不应该把错误结果写入缓存，可以在 <code>action</code> 里抛异常或返回 null，在 <code>CacheOrLoad</code> 里判断 token 有效性再决定是否缓存。</li>



<li><strong>网页授权 access_token 也适用</strong>：网页授权的 access_token 有效期也是 7200 秒，同样可以用这个模式缓存，但注意它的 key 要区分 openid 或 session。</li>
</ol>



<h4 class="wp-block-heading">改进版（带有效性校验）</h4>


<pre class="wp-block-code"><span><code class="hljs language-php"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> T CacheOrLoad&lt;T&gt;(string key, Func&lt;T&gt; action) where T : <span class="hljs-class"><span class="hljs-keyword">class</span>
</span>{
    lock (_lock)
    {
        <span class="hljs-keyword">var</span> token = System.Web.HttpRuntime.Cache.Get(key) <span class="hljs-keyword">as</span> T;
        <span class="hljs-keyword">if</span> (token == <span class="hljs-keyword">null</span>)
        {
            token = action();
            <span class="hljs-keyword">if</span> (token != <span class="hljs-keyword">null</span>)
            {
                System.Web.HttpRuntime.Cache.Add(
                    key,
                    token,
                    <span class="hljs-keyword">null</span>,
                    DateTime.Now.AddSeconds(<span class="hljs-number">7200</span>),
                    System.Web.Caching.Cache.NoSlidingExpiration,
                    System.Web.Caching.CacheItemPriority.<span class="hljs-keyword">Default</span>,
                    <span class="hljs-keyword">null</span>
                );
            }
        }
        <span class="hljs-keyword">return</span> token;
    }
}</code></span></pre>


<p class="wp-block-paragraph">这样改造后，Token 在 2 小时内只会向微信服务器请求一次，大幅减少不必要的网络调用，也符合微信接口调用的最佳实践。</p>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.foxdevelop.com/zh/2026/09/28/17-token%e4%bd%bf%e7%94%a8%e7%bc%93%e5%ad%98%e7%9a%84%e6%96%b9%e5%bc%8f%e6%9d%a5%e5%ad%98%e5%82%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>16-微信网页授权-通过code换取网页授权access_token</title>
		<link>https://www.foxdevelop.com/zh/2026/09/28/16-%e5%be%ae%e4%bf%a1%e7%bd%91%e9%a1%b5%e6%8e%88%e6%9d%83-%e9%80%9a%e8%bf%87code%e6%8d%a2%e5%8f%96%e7%bd%91%e9%a1%b5%e6%8e%88%e6%9d%83access_token/</link>
					<comments>https://www.foxdevelop.com/zh/2026/09/28/16-%e5%be%ae%e4%bf%a1%e7%bd%91%e9%a1%b5%e6%8e%88%e6%9d%83-%e9%80%9a%e8%bf%87code%e6%8d%a2%e5%8f%96%e7%bd%91%e9%a1%b5%e6%8e%88%e6%9d%83access_token/#respond</comments>
		
		<dc:creator><![CDATA[jack]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 01:20:38 +0000</pubDate>
				<category><![CDATA[微信公众平台开发ASP.NET Core MVC2版本]]></category>
		<guid isPermaLink="false">https://www.foxdevelop.com/?p=13066</guid>

					<description><![CDATA[通过 code 换取网页授权 access_token 首先 ...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">通过 code 换取网页授权 access_token</h3>



<p class="wp-block-paragraph">首先请注意，这里通过 code 换取的<strong>是一个特殊的网页授权 access_token</strong>，与基础支持中的 access_token（用于调用其他接口）<strong>不同</strong>。</p>



<p class="wp-block-paragraph">公众号可通过下述接口来获取网页授权 access_token。如果网页授权的作用域为 <code>snsapi_base</code>，则本步骤中获取到网页授权 access_token 的同时，也获取到了 <code>openid</code>，<code>snsapi_base</code> 式的网页授权流程即到此为止。</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>安全提醒</strong>：由于公众号的 secret 和获取到的 access_token 安全级别都非常高，必须只保存在服务器，不允许传给客户端。后续刷新 access_token、通过 access_token 获取用户信息等步骤，也必须从服务器发起。</p>
</blockquote>



<h4 class="wp-block-heading">请求方法</h4>



<p class="wp-block-paragraph">获取 code 后，请求以下链接获取 access_token：</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">https:<span class="hljs-comment">//api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&amp;secret=SECRET&amp;code=CODE&amp;grant_type=authorization_code</span></code></span></pre>


<h4 class="wp-block-heading">参数说明</h4>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>参数</th><th>是否必须</th><th>说明</th></tr></thead><tbody><tr><td>appid</td><td>是</td><td>公众号的唯一标识</td></tr><tr><td>secret</td><td>是</td><td>公众号的 appsecret</td></tr><tr><td>code</td><td>是</td><td>填写第一步获取的 code 参数</td></tr><tr><td>grant_type</td><td>是</td><td>填写为 authorization_code</td></tr></tbody></table></figure>



<h4 class="wp-block-heading">返回说明</h4>



<p class="wp-block-paragraph">正确时返回的 JSON 数据包如下：</p>


<pre class="wp-block-code"><span><code class="hljs language-json">{
  <span class="hljs-attr">"access_token"</span>: <span class="hljs-string">"ACCESS_TOKEN"</span>,
  <span class="hljs-attr">"expires_in"</span>: <span class="hljs-number">7200</span>,
  <span class="hljs-attr">"refresh_token"</span>: <span class="hljs-string">"REFRESH_TOKEN"</span>,
  <span class="hljs-attr">"openid"</span>: <span class="hljs-string">"OPENID"</span>,
  <span class="hljs-attr">"scope"</span>: <span class="hljs-string">"SCOPE"</span>
}</code></span></pre>


<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td>access_token</td><td>网页授权接口调用凭证，注意：此 access_token 与基础支持的 access_token 不同</td></tr><tr><td>expires_in</td><td>access_token 接口调用凭证超时时间，单位（秒）</td></tr><tr><td>refresh_token</td><td>用户刷新 access_token</td></tr><tr><td>openid</td><td>用户唯一标识，请注意，在未关注公众号时，用户访问公众号的网页，也会产生一个用户和公众号唯一的 OpenID</td></tr><tr><td>scope</td><td>用户授权的作用域，使用逗号（,）分隔</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">错误时微信会返回 JSON 数据包如下（示例为 Code 无效错误）：</p>


<pre class="wp-block-code"><span><code class="hljs language-json">{<span class="hljs-attr">"errcode"</span>:<span class="hljs-number">40029</span>,<span class="hljs-attr">"errmsg"</span>:<span class="hljs-string">"invalid code"</span>}</code></span></pre>


<h4 class="wp-block-heading">在 Manage 控制器中获取 code 并换取网页授权 access_token</h4>



<p class="wp-block-paragraph">用户同意授权后，微信会跳转回 <code>redirect_uri</code>，并附带 <code>code</code> 和 <code>state</code> 参数。我们在 Manage 控制器中接收这个 <code>code</code>，然后调用接口换取网页授权 access_token。</p>


<pre class="wp-block-code"><span><code class="hljs language-xml">public class HomeController : Controller
{
    public ActionResult Manage(string code, string state)
    {
        if (string.IsNullOrEmpty(code))
        {
            return Content("未获取到授权code");
        }

        // 第一步：用 code 换取网页授权 access_token
        var url = string.Format(
            "https://api.weixin.qq.com/sns/oauth2/access_token?appid={0}&amp;secret={1}&amp;code={2}&amp;grant_type=authorization_code",
            "wx51ebd98e1d633db6",
            "42a5564582bda88104367ea5851c9265",
            code
        );

        var json = HtmlHelper.HttpGet(url);
        var tokenResult = JsonHelper.DeserializeJsonToObject<span class="hljs-tag">&lt;<span class="hljs-name">dynamic</span>&gt;</span>(json);

        // 判断是否返回错误
        if (tokenResult.errcode != null)
        {
            return Content("获取网页授权access_token失败：" + tokenResult.errmsg);
        }

        // 拿到网页授权 access_token 和 openid
        string webAccessToken = tokenResult.access_token;
        string openid = tokenResult.openid;
        string refreshToken = tokenResult.refresh_token;
        string scope = tokenResult.scope;

        // 可以将 webAccessToken、openid 存入 Session 或缓存，供后续使用
        Session&#91;"WebAccessToken"] = webAccessToken;
        Session&#91;"OAuthOpenId"] = openid;

        // 第二步（下一步）：通过 webAccessToken 和 openid 获取用户信息
        // 这里先返回获取到的 token 信息，验证流程是否走通
        return Json(new
        {
            webAccessToken,
            openid,
            scope,
            tip = "接下来可以用 webAccessToken + openid 调用获取用户信息接口"
        }, JsonRequestBehavior.AllowGet);
    }
}</code></span></pre>


<h4 class="wp-block-heading">关键注意事项</h4>



<ol class="wp-block-list">
<li><strong>code 只能使用一次</strong>，5 分钟未用自动过期。调试时不要重复刷新同一个 code 的页面。</li>



<li><strong>网页授权 access_token 与基础 access_token 是两套东西</strong>，不要混用。基础 access_token 用于模板消息、自定义菜单等接口；网页授权 access_token 仅用于获取用户信息。</li>



<li><strong>secret 和 access_token 不要传到客户端</strong>，所有换取和刷新操作都在服务器端完成。</li>



<li>如果 scope 是 <code>snsapi_base</code>，到这一步就已经拿到了 <code>openid</code>，不需要再走获取用户信息的步骤。</li>



<li>如果 scope 是 <code>snsapi_userinfo</code>，接下来还需要用 <code>webAccessToken + openid</code> 调用获取用户基本信息接口，这个我们下一步再实现。</li>
</ol>



<p class="wp-block-paragraph"></p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.foxdevelop.com/zh/2026/09/28/16-%e5%be%ae%e4%bf%a1%e7%bd%91%e9%a1%b5%e6%8e%88%e6%9d%83-%e9%80%9a%e8%bf%87code%e6%8d%a2%e5%8f%96%e7%bd%91%e9%a1%b5%e6%8e%88%e6%9d%83access_token/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>15-微信网页授权的理解和第一步-用户同意授权获取</title>
		<link>https://www.foxdevelop.com/zh/2026/09/28/15-%e5%be%ae%e4%bf%a1%e7%bd%91%e9%a1%b5%e6%8e%88%e6%9d%83%e7%9a%84%e7%90%86%e8%a7%a3%e5%92%8c%e7%ac%ac%e4%b8%80%e6%ad%a5-%e7%94%a8%e6%88%b7%e5%90%8c%e6%84%8f%e6%8e%88%e6%9d%83%e8%8e%b7%e5%8f%96/</link>
					<comments>https://www.foxdevelop.com/zh/2026/09/28/15-%e5%be%ae%e4%bf%a1%e7%bd%91%e9%a1%b5%e6%8e%88%e6%9d%83%e7%9a%84%e7%90%86%e8%a7%a3%e5%92%8c%e7%ac%ac%e4%b8%80%e6%ad%a5-%e7%94%a8%e6%88%b7%e5%90%8c%e6%84%8f%e6%8e%88%e6%9d%83%e8%8e%b7%e5%8f%96/#respond</comments>
		
		<dc:creator><![CDATA[jack]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 01:16:56 +0000</pubDate>
				<category><![CDATA[微信公众平台开发ASP.NET Core MVC2版本]]></category>
		<guid isPermaLink="false">https://www.foxdevelop.com/?p=13065</guid>

					<description><![CDATA[网页授权获取用户基本信息 模板消息里点击详情可以跳转到某个页 ...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">网页授权获取用户基本信息</h3>



<p class="wp-block-paragraph">模板消息里点击详情可以跳转到某个页面，但模板本身是微信内部固定好的，不是随便设计。</p>



<p class="wp-block-paragraph">如果用户在微信客户端中访问第三方网页，公众号可以通过微信网页授权机制，来获取用户基本信息，进而实现业务逻辑。</p>



<h4 class="wp-block-heading">网页授权回调域名说明</h4>



<ol class="wp-block-list">
<li>在微信公众号请求用户网页授权之前，开发者需要先到公众平台官网中的“开发 &#8211; 接口权限 &#8211; 网页服务 &#8211; 网页帐号 &#8211; 网页授权获取用户基本信息”里，修改授权回调域名。这里填写的是域名（字符串），不是 URL，因此请勿加 http:// 等协议头。</li>



<li>授权回调域名配置规范为全域名。比如需要网页授权的域名为：<a href="https://tencent.yuanbao/www.qq.com">www.qq.com</a>，配置以后此域名下面的页面 <a href="http://www.qq.com/music.html">http://www.qq.com/music.html</a> 、 <a href="http://www.qq.com/login.html">http://www.qq.com/login.html</a> 都可以进行 OAuth2.0 鉴权；但 <a href="http://pay.qq.com/">http://pay.qq.com</a> 、 <a href="http://music.qq.com/">http://music.qq.com</a> 、 <a href="http://qq.com/">http://qq.com</a> 无法进行 OAuth2.0 鉴权。</li>



<li>如果公众号登录授权给了第三方开发者来进行管理，则不必做任何设置，由第三方代替公众号实现网页授权即可。</li>
</ol>



<h4 class="wp-block-heading">两种 scope 的区别</h4>



<ol class="wp-block-list">
<li>以 snsapi_base 为 scope 发起的网页授权，用来获取进入页面的用户的 openid，是静默授权并自动跳转到回调页。用户感知就是直接进入了回调页（往往是业务页面）。</li>



<li>以 snsapi_userinfo 为 scope 发起的网页授权，用来获取用户的基本信息。这种授权需要用户手动同意，用户同意过后，无须关注公众号，也可在授权后获取该用户的基本信息。</li>



<li>用户管理类接口中的“获取用户基本信息接口”，是在用户和公众号产生消息交互或关注后事件推送后，才能根据用户 OpenID 来获取用户基本信息。这个接口，包括其他微信接口，都需要该用户（openid）关注了公众号后，才能调用成功。</li>
</ol>



<h4 class="wp-block-heading">网页授权 access_token 和普通 access_token 的区别</h4>



<ol class="wp-block-list">
<li>微信网页授权是通过 OAuth2.0 机制实现的，用户授权给公众号后，公众号可以获取到网页授权特有的接口调用凭证（网页授权 access_token），通过它可以进行授权后接口调用，如获取用户基本信息。</li>



<li>其他微信接口，需要通过基础支持中的“获取 access_token”接口来获取普通 access_token 调用。</li>
</ol>



<h4 class="wp-block-heading">UnionID 机制</h4>



<ol class="wp-block-list">
<li>网页授权获取用户基本信息也遵循 UnionID 机制。如果开发者有多个公众号，或在公众号、移动应用之间统一用户帐号，需要前往微信开放平台（open.weixin.qq.com）绑定公众号后，才能利用 UnionID 机制满足需求。</li>



<li>UnionID 机制作用：如果开发者拥有多个移动应用、网站应用和公众帐号，可通过用户基本信息中的 unionid 区分用户唯一性。同一用户，对同一个微信开放平台下的不同应用（移动应用、网站应用和公众帐号），unionid 是相同的。</li>
</ol>



<h4 class="wp-block-heading">特殊场景下的静默授权</h4>



<ol class="wp-block-list">
<li>以 snsapi_base 为 scope 的网页授权，是静默授权，用户无感知。</li>



<li>对于已关注公众号的用户，如果从公众号会话或者自定义菜单进入本公众号的网页授权页，即使是 scope 为 snsapi_userinfo，也是静默授权，用户无感知。</li>
</ol>



<h4 class="wp-block-heading">网页授权流程</h4>



<ol class="wp-block-list">
<li>引导用户进入授权页面同意授权，获取 code</li>



<li>通过 code 换取网页授权 access_token（与基础支持中的 access_token 不同）</li>



<li>如果需要，开发者可以刷新网页授权 access_token，避免过期</li>



<li>通过网页授权 access_token 和 openid 获取用户基本信息（支持 UnionID 机制）</li>
</ol>



<h4 class="wp-block-heading">配置授权回调域名</h4>



<p class="wp-block-paragraph">在测试账号管理页面中配置网页授权回调域名。</p>



<h4 class="wp-block-heading">修改菜单地址为网页授权地址</h4>


<pre class="wp-block-code"><span><code class="hljs language-javascript">secondButton.Add(<span class="hljs-keyword">new</span>
{
    type = <span class="hljs-string">"view"</span>,
    name = <span class="hljs-string">"管理后台"</span>,
    url = string.Format(
        <span class="hljs-string">"https://open.weixin.qq.com/connect/oauth2/authorize?appid={0}&amp;redirect_uri={1}&amp;response_type=code&amp;scope=snsapi_userinfo&amp;state=STATE#wechat_redirect"</span>,
        APPID,
        <span class="hljs-string">"http%3a%2f%2f2l1941590s.imwork.net%2fhome%2fmanage"</span>)
});</code></span></pre>


<p class="wp-block-paragraph">记得要对回调地址进行 URL 编码：</p>


<pre class="wp-block-code"><span><code class="hljs language-css"><span class="hljs-selector-tag">http</span>%3<span class="hljs-selector-tag">a</span>%2<span class="hljs-selector-tag">f</span>%2<span class="hljs-selector-tag">f2l1941590s</span><span class="hljs-selector-class">.imwork</span><span class="hljs-selector-class">.net</span>%2<span class="hljs-selector-tag">fhome</span>%2<span class="hljs-selector-tag">fmanage</span></code></span></pre>


<h4 class="wp-block-heading">用户同意授权后</h4>



<p class="wp-block-paragraph">如果用户同意授权，页面将跳转至：</p>


<pre class="wp-block-code"><span><code class="hljs">redirect_uri/?code=CODE&amp;state=STATE</code></span></pre>


<p class="wp-block-paragraph">code 说明：code 作为换取 access_token 的票据，每次用户授权带上的 code 都不一样，code 只能使用一次，5 分钟未被使用自动过期。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.foxdevelop.com/zh/2026/09/28/15-%e5%be%ae%e4%bf%a1%e7%bd%91%e9%a1%b5%e6%8e%88%e6%9d%83%e7%9a%84%e7%90%86%e8%a7%a3%e5%92%8c%e7%ac%ac%e4%b8%80%e6%ad%a5-%e7%94%a8%e6%88%b7%e5%90%8c%e6%84%8f%e6%8e%88%e6%9d%83%e8%8e%b7%e5%8f%96/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>14-发送模板消息</title>
		<link>https://www.foxdevelop.com/zh/2026/09/28/14-%e5%8f%91%e9%80%81%e6%a8%a1%e6%9d%bf%e6%b6%88%e6%81%af/</link>
					<comments>https://www.foxdevelop.com/zh/2026/09/28/14-%e5%8f%91%e9%80%81%e6%a8%a1%e6%9d%bf%e6%b6%88%e6%81%af/#respond</comments>
		
		<dc:creator><![CDATA[jack]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 01:15:23 +0000</pubDate>
				<category><![CDATA[微信公众平台开发ASP.NET Core MVC2版本]]></category>
		<guid isPermaLink="false">https://www.foxdevelop.com/?p=13068</guid>

					<description><![CDATA[发送模板消息 在上一节课中，我们获取到了当前公众号的模板 I ...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">发送模板消息</h3>



<p class="wp-block-paragraph">在上一节课中，我们获取到了当前公众号的模板 ID，接下来就可以使用这个模板来发送模板消息。</p>



<h4 class="wp-block-heading">接口说明</h4>



<p class="wp-block-paragraph">HTTP 请求方式：POST</p>



<p class="wp-block-paragraph"><a href="https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN">https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN</a></p>



<p class="wp-block-paragraph">替换模板占位符时，还可以为每个字段设置显示颜色。</p>



<h4 class="wp-block-heading">Handler 实现</h4>


<pre class="wp-block-code"><span><code class="hljs language-xml">public class TemplateSendHandle : WeiXinHandlerBase, IWeiXinHandler
{
    private string url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={0}";

    public T DoGet<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(params string&#91;] param) where T : class
    {
        throw new NotImplementedException();
    }

    public T DoPost<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(params string&#91;] param) where T : class
    {
        var uploadUrl = string.Format(url, accessTokenInfo.access_token);
        var user = new UserGetHandler().DoGet<span class="hljs-tag">&lt;<span class="hljs-name">UserInfo</span>&gt;</span>();

        var post = new
        {
            touser = user.data.openid&#91;0], // 发给第一个人
            template_id = "coA2OijGsDxN3b2i48D0vaPLd5BraRQnDYcJ8MazzAc",
            url = "http://www.bamn.cn",
            data = new
            {
                first = new { value = "恭喜你购买成功！", color = "#173177" },
                orderMoneySum = new { value = "1000！", color = "#183177" },
                orderProductName = new { value = "苹果电脑 MACBOOK PRO", color = "#173177" },
                Remark = new { value = "备注，分12期还款", color = "#173377" }
            }
        };

        var json = JsonHelper.SerializeObject(post);
        var resultjson = HtmlHelper.HttpPost(uploadUrl, json);
        var output = JsonHelper.DeserializeJsonToObject<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(resultjson);
        return output;
    }
}</code></span></pre>


<h4 class="wp-block-heading">控制器中调用</h4>


<pre class="wp-block-code"><span><code class="hljs language-php"><span class="hljs-keyword">public</span> ActionResult TemplateSend()
{
    <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">new</span> TemplateSendHandle().DoPost&lt;dynamic&gt;();
    <span class="hljs-keyword">return</span> Json(result);
}</code></span></pre>


<h4 class="wp-block-heading">调用测试</h4>



<p class="wp-block-paragraph">访问地址：</p>



<p class="wp-block-paragraph"><a href="http://xxxxx.imwork.net/home/TemplateSend">http://xxxxx.imwork.net/home/TemplateSend</a></p>



<p class="wp-block-paragraph">返回结果：</p>


<pre class="wp-block-code"><span><code class="hljs language-json">{<span class="hljs-attr">"errcode"</span>:<span class="hljs-number">0</span>,<span class="hljs-attr">"errmsg"</span>:<span class="hljs-string">"ok"</span>,<span class="hljs-attr">"msgid"</span>:<span class="hljs-number">451307458980315137</span>}</code></span></pre>


<p class="wp-block-paragraph">errcode 为 0 表示发送成功。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.foxdevelop.com/zh/2026/09/28/14-%e5%8f%91%e9%80%81%e6%a8%a1%e6%9d%bf%e6%b6%88%e6%81%af/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>13-获取模板列表</title>
		<link>https://www.foxdevelop.com/zh/2026/09/28/13-%e8%8e%b7%e5%8f%96%e6%a8%a1%e6%9d%bf%e5%88%97%e8%a1%a8/</link>
					<comments>https://www.foxdevelop.com/zh/2026/09/28/13-%e8%8e%b7%e5%8f%96%e6%a8%a1%e6%9d%bf%e5%88%97%e8%a1%a8/#respond</comments>
		
		<dc:creator><![CDATA[jack]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 01:11:30 +0000</pubDate>
				<category><![CDATA[微信公众平台开发ASP.NET Core MVC2版本]]></category>
		<guid isPermaLink="false">https://www.foxdevelop.com/?p=13060</guid>

					<description><![CDATA[获取公众号下所有模板列表 上面配置完行业以后，就可以获取该行 ...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">获取公众号下所有模板列表</h3>



<p class="wp-block-paragraph">上面配置完行业以后，就可以获取该行业对应的模板。通过获取模板内容，可以看到里面有很多占位符，后续发送模板消息时再填充这些数据。</p>



<p class="wp-block-paragraph">例如模板内容：</p>


<pre class="wp-block-code"><span><code class="hljs">{{result.DATA}}

领奖金额:{{withdrawMoney.DATA}}
领奖   时间:{{withdrawTime.DATA}}
银行信息:{{cardInfo.DATA}}
到账时间: {{arrivedTime.DATA}}
{{remark.DATA}}</code></span></pre>


<p class="wp-block-paragraph">这些 <code>{{xxx.DATA}}</code> 就是模板占位符，都可以在发送模板消息时配置具体值。</p>



<h4 class="wp-block-heading">获取模板列表接口</h4>



<p class="wp-block-paragraph">获取已添加至帐号下的所有模板列表，也可以在微信公众平台后台查看。微信同样提供了接口调用方式。</p>



<p class="wp-block-paragraph">接口调用请求说明：</p>



<p class="wp-block-paragraph">HTTP 请求方式：GET</p>



<p class="wp-block-paragraph"><a href="https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=ACCESS_TOKEN">https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=ACCESS_TOKEN</a></p>



<h4 class="wp-block-heading">Handler 实现</h4>


<pre class="wp-block-code"><span><code class="hljs language-xml">public class AllPrivateTemplateHandler : WeiXinHandlerBase, IWeiXinHandler
{
    private string url = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token={0}";

    public T DoGet<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(params string&#91;] param) where T : class
    {
        url = string.Format(url, accessTokenInfo.access_token);
        var json = HtmlHelper.HttpGet(url);
        var output = JsonHelper.DeserializeJsonToObject<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(json);
        return output;
    }

    public T DoPost<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(params string&#91;] param) where T : class
    {
        throw new System.NotImplementedException();
    }
}</code></span></pre>


<h4 class="wp-block-heading">控制器中调用</h4>


<pre class="wp-block-code"><span><code class="hljs language-php"><span class="hljs-keyword">public</span> ActionResult GetAllPrivateTemplate()
{
    <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">new</span> AllPrivateTemplateHandler().DoGet&lt;dynamic&gt;();
    <span class="hljs-keyword">return</span> Json(result);
}</code></span></pre>


<h4 class="wp-block-heading">返回结果示例</h4>


<pre class="wp-block-code"><span><code class="hljs language-json">{
  <span class="hljs-attr">"template_list"</span>: &#91;
    {
      <span class="hljs-attr">"template_id"</span>: <span class="hljs-string">"coA2OijGsDxN3b2i48D0vaPLd5BraRQnDYcJ8MazzAc"</span>,
      <span class="hljs-attr">"title"</span>: <span class="hljs-string">"订单支付成功"</span>,
      <span class="hljs-attr">"primary_industry"</span>: <span class="hljs-string">"IT科技"</span>,
      <span class="hljs-attr">"deputy_industry"</span>: <span class="hljs-string">"互联网|电子商务"</span>,
      <span class="hljs-attr">"content"</span>: <span class="hljs-string">"{{first.DATA}}\n\n支付金额：{{orderMoneySum.DATA}}\n商品信息：{{orderProductName.DATA}}\n{{Remark.DATA}}"</span>,
      <span class="hljs-attr">"example"</span>: <span class="hljs-string">"我们已收到您的货款，开始为您打包商品，请耐心等待: )\n支付金额：30.00元\n商品信息：我是商品名字\n\n如有问题请致电400-828-1878或直接在微信留言，小易将第一时间为您服务！"</span>
    }
  ]
}</code></span></pre>


<p class="wp-block-paragraph">拿到 <code>template_id</code> 和模板里的 <code>{{xxx.DATA}}</code> 占位符后，就可以在发送模板消息时按字段填充数据。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.foxdevelop.com/zh/2026/09/28/13-%e8%8e%b7%e5%8f%96%e6%a8%a1%e6%9d%bf%e5%88%97%e8%a1%a8/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>12-模板消息接口-设置所属行业</title>
		<link>https://www.foxdevelop.com/zh/2026/09/28/12-%e6%a8%a1%e6%9d%bf%e6%b6%88%e6%81%af%e6%8e%a5%e5%8f%a3-%e8%ae%be%e7%bd%ae%e6%89%80%e5%b1%9e%e8%a1%8c%e4%b8%9a/</link>
					<comments>https://www.foxdevelop.com/zh/2026/09/28/12-%e6%a8%a1%e6%9d%bf%e6%b6%88%e6%81%af%e6%8e%a5%e5%8f%a3-%e8%ae%be%e7%bd%ae%e6%89%80%e5%b1%9e%e8%a1%8c%e4%b8%9a/#respond</comments>
		
		<dc:creator><![CDATA[jack]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 01:11:00 +0000</pubDate>
				<category><![CDATA[微信公众平台开发ASP.NET Core MVC2版本]]></category>
		<guid isPermaLink="false">https://www.foxdevelop.com/?p=13059</guid>

					<description><![CDATA[设置公众号模板消息所属行业 模板消息仅用于公众号向用户发送重 ...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">设置公众号模板消息所属行业</h3>



<p class="wp-block-paragraph">模板消息仅用于公众号向用户发送重要的服务通知，只能用于符合要求的服务场景中，如信用卡刷卡通知、商品购买成功通知等。不支持广告等营销类消息，以及其他所有可能对用户造成骚扰的消息。</p>



<p class="wp-block-paragraph">文档地址：</p>



<p class="wp-block-paragraph"><a href="https://mp.weixin.qq.com/wiki?t=resource/res_main&amp;id=mp1433751277">https://mp.weixin.qq.com/wiki?t=resource/res_main&amp;id=mp1433751277</a></p>



<h4 class="wp-block-heading">设置所属行业</h4>



<p class="wp-block-paragraph">设置行业可以在微信公众平台后台完成，每月可修改行业 1 次。帐号只能使用所属行业中相关的模板。为方便第三方开发者，微信也提供通过接口调用修改账号所属行业的方式。</p>



<p class="wp-block-paragraph">接口调用请求说明：</p>



<p class="wp-block-paragraph">HTTP 请求方式：POST</p>



<p class="wp-block-paragraph"><a href="https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=ACCESS_TOKEN">https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token=ACCESS_TOKEN</a></p>



<p class="wp-block-paragraph">POST 数据示例：</p>


<pre class="wp-block-code"><span><code class="hljs language-json">{
  <span class="hljs-attr">"industry_id1"</span>: <span class="hljs-string">"1"</span>,
  <span class="hljs-attr">"industry_id2"</span>: <span class="hljs-string">"4"</span>
}</code></span></pre>


<p class="wp-block-paragraph">参数说明：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>参数</th><th>是否必须</th><th>说明</th></tr></thead><tbody><tr><td>access_token</td><td>是</td><td>接口调用凭证</td></tr><tr><td>industry_id1</td><td>是</td><td>公众号模板消息所属行业编号</td></tr><tr><td>industry_id2</td><td>是</td><td>公众号模板消息所属行业编号</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">说白了，不同行业有不同的模板格式，需要通过接口设置公众号所属行业。具体行业代码可参考上面的文档地址。</p>



<h4 class="wp-block-heading">Handler 实现</h4>


<pre class="wp-block-code"><span><code class="hljs language-xml">public class ApiSetIndustryHandler : WeiXinHandlerBase, IWeiXinHandler
{
    private string url = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token={0}";

    public T DoGet<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(params string&#91;] param) where T : class
    {
        throw new NotImplementedException();
    }

    public T DoPost<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(params string&#91;] param) where T : class
    {
        var para = new
        {
            industry_id1 = "1",
            industry_id2 = "10"
        };

        var json = JsonHelper.SerializeObject(para);
        url = string.Format(url, accessTokenInfo.access_token);

        var content = HtmlHelper.HttpPost(url, json);
        return JsonHelper.DeserializeJsonToObject<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(content);
    }
}</code></span></pre>


<h4 class="wp-block-heading">控制器中调用</h4>


<pre class="wp-block-code"><span><code class="hljs language-php"><span class="hljs-keyword">public</span> ActionResult ApiSetIndustry()
{
    <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">new</span> ApiSetIndustryHandler().DoPost&lt;dynamic&gt;();
    <span class="hljs-keyword">return</span> Json(result);
}</code></span></pre>


<h4 class="wp-block-heading">访问测试</h4>



<p class="wp-block-paragraph"><a href="http://xxxxx.imwork.net/home/ApiSetIndustry">http://xxxxx.imwork.net/home/ApiSetIndustry</a></p>



<p class="wp-block-paragraph">返回：</p>


<pre class="wp-block-code"><span><code class="hljs language-json">{<span class="hljs-attr">"errcode"</span>:<span class="hljs-number">43100</span>,<span class="hljs-attr">"errmsg"</span>:<span class="hljs-string">"change template too frequently hint: &#91;kLqX706961961]"</span>}</code></span></pre>


<p class="wp-block-paragraph">原因是：公众号所属行业一个月只能设置一次。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.foxdevelop.com/zh/2026/09/28/12-%e6%a8%a1%e6%9d%bf%e6%b6%88%e6%81%af%e6%8e%a5%e5%8f%a3-%e8%ae%be%e7%bd%ae%e6%89%80%e5%b1%9e%e8%a1%8c%e4%b8%9a/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>11-关注或者取消关注事件-发送欢迎消息</title>
		<link>https://www.foxdevelop.com/zh/2026/09/28/11-%e5%85%b3%e6%b3%a8%e6%88%96%e8%80%85%e5%8f%96%e6%b6%88%e5%85%b3%e6%b3%a8%e4%ba%8b%e4%bb%b6-%e5%8f%91%e9%80%81%e6%ac%a2%e8%bf%8e%e6%b6%88%e6%81%af/</link>
					<comments>https://www.foxdevelop.com/zh/2026/09/28/11-%e5%85%b3%e6%b3%a8%e6%88%96%e8%80%85%e5%8f%96%e6%b6%88%e5%85%b3%e6%b3%a8%e4%ba%8b%e4%bb%b6-%e5%8f%91%e9%80%81%e6%ac%a2%e8%bf%8e%e6%b6%88%e6%81%af/#respond</comments>
		
		<dc:creator><![CDATA[jack]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 01:10:25 +0000</pubDate>
				<category><![CDATA[微信公众平台开发ASP.NET Core MVC2版本]]></category>
		<guid isPermaLink="false">https://www.foxdevelop.com/?p=13056</guid>

					<description><![CDATA[关注/取消关注事件处理 当用户关注或取消关注公众号时，微信会 ...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">关注/取消关注事件处理</h3>



<p class="wp-block-paragraph">当用户关注或取消关注公众号时，微信会推送一条事件消息到开发者填写的 URL 接口。我们可以捕捉这个事件，判断是订阅还是取消订阅，从而下发欢迎消息或做帐号解绑等操作。</p>



<p class="wp-block-paragraph">为保护用户数据隐私，开发者收到用户取消关注事件时需要删除该用户的所有信息。</p>



<h4 class="wp-block-heading">接口说明</h4>



<p class="wp-block-paragraph">文档地址：</p>



<p class="wp-block-paragraph"><a href="https://mp.weixin.qq.com/wiki?t=resource/res_main&amp;id=mp1421140454">https://mp.weixin.qq.com/wiki?t=resource/res_main&amp;id=mp1421140454</a></p>



<p class="wp-block-paragraph">推送 XML 数据包示例：</p>


<pre class="wp-block-code"><span><code class="hljs language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">xml</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">ToUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;toUser]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">ToUserName</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">FromUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;FromUser]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">FromUserName</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">CreateTime</span>&gt;</span>123456789<span class="hljs-tag">&lt;/<span class="hljs-name">CreateTime</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">MsgType</span>&gt;</span>&lt;!&#91;CDATA&#91;event]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">MsgType</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">Event</span>&gt;</span>&lt;!&#91;CDATA&#91;subscribe]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">Event</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">xml</span>&gt;</span></code></span></pre>


<p class="wp-block-paragraph">参数说明：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td>ToUserName</td><td>开发者微信号</td></tr><tr><td>FromUserName</td><td>发送方帐号（一个 OpenID）</td></tr><tr><td>CreateTime</td><td>消息创建时间（整型）</td></tr><tr><td>MsgType</td><td>消息类型，event</td></tr><tr><td>Event</td><td>事件类型，subscribe（订阅）、unsubscribe（取消订阅）</td></tr></tbody></table></figure>



<h4 class="wp-block-heading">控制器中处理关注/取消关注事件</h4>



<p class="wp-block-paragraph">在 Common 方法的 event 分支中增加 subscribe 和 unsubscribe 的判断：</p>


<pre class="wp-block-code"><span><code class="hljs language-xml">case "event":
    switch (Event.InnerText.ToLower())
    {
        case "click":
            string returnXml2 = string.Format(@"<span class="hljs-tag">&lt;<span class="hljs-name">xml</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">ToUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;{0}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">ToUserName</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">FromUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;{1}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">FromUserName</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">CreateTime</span>&gt;</span>{2}<span class="hljs-tag">&lt;/<span class="hljs-name">CreateTime</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">MsgType</span>&gt;</span>&lt;!&#91;CDATA&#91;{3}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">MsgType</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">Content</span>&gt;</span>&lt;!&#91;CDATA&#91;{4}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">Content</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">xml</span>&gt;</span>",
                FromUserName.InnerText,
                ToUserName.InnerText,
                OtherUtil.GetTimestamp(DateTime.Now),
                "text",
                "请不要点击。");
            return this.Content(returnXml2);

        case "subscribe":
            string returnXml3 = string.Format(@"<span class="hljs-tag">&lt;<span class="hljs-name">xml</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">ToUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;{0}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">ToUserName</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">FromUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;{1}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">FromUserName</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">CreateTime</span>&gt;</span>{2}<span class="hljs-tag">&lt;/<span class="hljs-name">CreateTime</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">MsgType</span>&gt;</span>&lt;!&#91;CDATA&#91;{3}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">MsgType</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">Content</span>&gt;</span>&lt;!&#91;CDATA&#91;{4}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">Content</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">xml</span>&gt;</span>",
                FromUserName.InnerText,
                ToUserName.InnerText,
                OtherUtil.GetTimestamp(DateTime.Now),
                "text",
                "欢迎关注。");
            return this.Content(returnXml3);

        case "unsubscribe":
            // 这里应该做一些清理用户信息的操作，发信息给它已经没有用了
            break;

        default:
            break;
    }
    break;</code></span></pre>]]></content:encoded>
					
					<wfw:commentRss>https://www.foxdevelop.com/zh/2026/09/28/11-%e5%85%b3%e6%b3%a8%e6%88%96%e8%80%85%e5%8f%96%e6%b6%88%e5%85%b3%e6%b3%a8%e4%ba%8b%e4%bb%b6-%e5%8f%91%e9%80%81%e6%ac%a2%e8%bf%8e%e6%b6%88%e6%81%af/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>10-菜单事件托送接收</title>
		<link>https://www.foxdevelop.com/zh/2026/09/28/10-%e8%8f%9c%e5%8d%95%e4%ba%8b%e4%bb%b6%e6%89%98%e9%80%81%e6%8e%a5%e6%94%b6/</link>
					<comments>https://www.foxdevelop.com/zh/2026/09/28/10-%e8%8f%9c%e5%8d%95%e4%ba%8b%e4%bb%b6%e6%89%98%e9%80%81%e6%8e%a5%e6%94%b6/#respond</comments>
		
		<dc:creator><![CDATA[jack]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 01:05:04 +0000</pubDate>
				<category><![CDATA[微信公众平台开发ASP.NET Core MVC2版本]]></category>
		<guid isPermaLink="false">https://www.foxdevelop.com/?p=13052</guid>

					<description><![CDATA[自定义菜单点击事件处理 当用户点击某个菜单后，微信服务器会发 ...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">自定义菜单点击事件处理</h3>



<p class="wp-block-paragraph">当用户点击某个菜单后，微信服务器会发送一个 XML 文档到我们服务器上配置的接口地址（即之前配置的 Common 接口）。我们可以解析这个 XML 文档来获取点击事件信息。</p>



<h4 class="wp-block-heading">自定义菜单事件推送说明</h4>



<p class="wp-block-paragraph">用户点击自定义菜单后，微信会把点击事件推送给开发者。注意：点击菜单弹出子菜单不会产生上报。</p>



<p class="wp-block-paragraph">点击菜单拉取消息时的事件推送 XML 示例：</p>


<pre class="wp-block-code"><span><code class="hljs language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">xml</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">ToUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;toUser]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">ToUserName</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">FromUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;FromUser]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">FromUserName</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">CreateTime</span>&gt;</span>123456789<span class="hljs-tag">&lt;/<span class="hljs-name">CreateTime</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">MsgType</span>&gt;</span>&lt;!&#91;CDATA&#91;event]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">MsgType</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">Event</span>&gt;</span>&lt;!&#91;CDATA&#91;CLICK]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">Event</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">EventKey</span>&gt;</span>&lt;!&#91;CDATA&#91;EVENTKEY]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">EventKey</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">xml</span>&gt;</span></code></span></pre>


<p class="wp-block-paragraph">参数说明：</p>



<figure class="wp-block-table"><table class="has-fixed-layout"><thead><tr><th>参数</th><th>描述</th></tr></thead><tbody><tr><td>ToUserName</td><td>开发者微信号</td></tr><tr><td>FromUserName</td><td>发送方帐号（一个 OpenID）</td></tr><tr><td>CreateTime</td><td>消息创建时间（整型）</td></tr><tr><td>MsgType</td><td>消息类型，event</td></tr><tr><td>Event</td><td>事件类型，CLICK</td></tr><tr><td>EventKey</td><td>事件 KEY 值，与自定义菜单接口中 KEY 值对应</td></tr></tbody></table></figure>



<p class="wp-block-paragraph">其中 EventKey 对应之前新增菜单时配置的 key，例如 <code>V1001_TODAY_MUSIC</code>。通过这个值可以判断是哪个按钮被点击了。</p>



<h4 class="wp-block-heading">控制器中处理菜单点击事件</h4>



<p class="wp-block-paragraph">在 Common 方法的 POST 分支中增加对 event 类型的处理：</p>


<pre class="wp-block-code"><span><code class="hljs language-xml">&#91;HttpPost]
public IActionResult Common()
{
    XmlDocument xmldoc = new XmlDocument();
    xmldoc.Load(Request.Body);

    XmlNode MsgType = xmldoc.SelectSingleNode("/xml/MsgType");
    XmlNode ToUserName = xmldoc.SelectSingleNode("/xml/ToUserName");
    XmlNode FromUserName = xmldoc.SelectSingleNode("/xml/FromUserName");
    XmlNode Content = xmldoc.SelectSingleNode("/xml/Content");
    XmlNode Event = xmldoc.SelectSingleNode("/xml/Event");

    switch (MsgType.InnerText)
    {
        case "text":
            var ret = "你好吗";
            if (Content.InnerText.Contains("天气"))
            {
                ret = "21摄氏度";
            }
            string returnXml = string.Format(@"<span class="hljs-tag">&lt;<span class="hljs-name">xml</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">ToUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;{0}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">ToUserName</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">FromUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;{1}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">FromUserName</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">CreateTime</span>&gt;</span>{2}<span class="hljs-tag">&lt;/<span class="hljs-name">CreateTime</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">MsgType</span>&gt;</span>&lt;!&#91;CDATA&#91;{3}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">MsgType</span>&gt;</span>
                <span class="hljs-tag">&lt;<span class="hljs-name">Content</span>&gt;</span>&lt;!&#91;CDATA&#91;{4}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">Content</span>&gt;</span>
                <span class="hljs-tag">&lt;/<span class="hljs-name">xml</span>&gt;</span>",
                FromUserName.InnerText,
                ToUserName.InnerText,
                OtherUtil.GetTimestamp(DateTime.Now),
                "text",
                ret);
            return this.Content(returnXml);

        case "event":
            switch (Event.InnerText.ToLower())
            {
                case "click":
                    string returnXml2 = string.Format(@"<span class="hljs-tag">&lt;<span class="hljs-name">xml</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">ToUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;{0}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">ToUserName</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">FromUserName</span>&gt;</span>&lt;!&#91;CDATA&#91;{1}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">FromUserName</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">CreateTime</span>&gt;</span>{2}<span class="hljs-tag">&lt;/<span class="hljs-name">CreateTime</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">MsgType</span>&gt;</span>&lt;!&#91;CDATA&#91;{3}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">MsgType</span>&gt;</span>
                        <span class="hljs-tag">&lt;<span class="hljs-name">Content</span>&gt;</span>&lt;!&#91;CDATA&#91;{4}]]&gt;<span class="hljs-tag">&lt;/<span class="hljs-name">Content</span>&gt;</span>
                        <span class="hljs-tag">&lt;/<span class="hljs-name">xml</span>&gt;</span>",
                        FromUserName.InnerText,
                        ToUserName.InnerText,
                        OtherUtil.GetTimestamp(DateTime.Now),
                        "text",
                        "请不要点击。");
                    return this.Content(returnXml2);

                default:
                    break;
            }
            break;

        default:
            break;
    }

    return this.Content("");
}</code></span></pre>]]></content:encoded>
					
					<wfw:commentRss>https://www.foxdevelop.com/zh/2026/09/28/10-%e8%8f%9c%e5%8d%95%e4%ba%8b%e4%bb%b6%e6%89%98%e9%80%81%e6%8e%a5%e6%94%b6/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>09-公众号菜单管理</title>
		<link>https://www.foxdevelop.com/zh/2026/09/28/09-%e5%85%ac%e4%bc%97%e5%8f%b7%e8%8f%9c%e5%8d%95%e7%ae%a1%e7%90%86/</link>
					<comments>https://www.foxdevelop.com/zh/2026/09/28/09-%e5%85%ac%e4%bc%97%e5%8f%b7%e8%8f%9c%e5%8d%95%e7%ae%a1%e7%90%86/#respond</comments>
		
		<dc:creator><![CDATA[jack]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 01:04:22 +0000</pubDate>
				<category><![CDATA[微信公众平台开发ASP.NET Core MVC2版本]]></category>
		<guid isPermaLink="false">https://www.foxdevelop.com/?p=13051</guid>

					<description><![CDATA[自定义菜单管理 公众号底部会显示菜单栏，这些菜单栏可以在微信 ...]]></description>
										<content:encoded><![CDATA[
<h3 class="wp-block-heading">自定义菜单管理</h3>



<p class="wp-block-paragraph">公众号底部会显示菜单栏，这些菜单栏可以在微信公众平台后台管理，也可以使用公众平台提供的接口进行管理，调用 POST 方法把菜单的 JSON 文本推送到微信服务器即可。</p>



<h4 class="wp-block-heading">接口说明</h4>



<p class="wp-block-paragraph">文档地址：</p>



<p class="wp-block-paragraph"><a href="https://mp.weixin.qq.com/wiki?t=resource/res_main&amp;id=mp1421141013">https://mp.weixin.qq.com/wiki?t=resource/res_main&amp;id=mp1421141013</a></p>



<p class="wp-block-paragraph">自定义菜单规则：</p>



<ul class="wp-block-list">
<li>最多包括 3 个一级菜单，每个一级菜单最多包含 5 个二级菜单</li>



<li>一级菜单最多 4 个汉字，二级菜单最多 7 个汉字，多出来的部分以&#8221;&#8230;&#8221;代替</li>



<li>自定义菜单接口可实现多种类型按钮：click、view 等</li>
</ul>



<p class="wp-block-paragraph">HTTP 请求方式：POST（请使用 https 协议）</p>



<p class="wp-block-paragraph"><a href="https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN">https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN</a></p>



<p class="wp-block-paragraph">每次创建或修改菜单时，需要把完整的菜单结构全部发送过去。</p>



<h4 class="wp-block-heading">添加 MenuCreateHandle</h4>


<pre class="wp-block-code"><span><code class="hljs language-xml">public class MenuCreateHandle : WeiXinHandlerBase, IWeiXinHandler
{
    private string url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token={0}";

    public T DoGet<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(params string&#91;] param) where T : class
    {
        throw new NotImplementedException();
    }

    public T DoPost<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(params string&#91;] param) where T : class
    {
        var uploadUrl = string.Format(url, accessTokenInfo.access_token);
        // view表示网页类型，click表示点击类型，miniprogram表示小程序类型
        var firstButton = new List<span class="hljs-tag">&lt;<span class="hljs-name">object</span>&gt;</span>();
        firstButton.Add(new { type = "click", name = "课程", key = "V1001_TODAY_MUSIC" });

        var secondButton = new List<span class="hljs-tag">&lt;<span class="hljs-name">object</span>&gt;</span>();
        secondButton.Add(new { type = "view", name = "管理后台", url = "http://www.bamn.cn" });
        secondButton.Add(new { type = "click", name = "赞一下我们", key = "V1001_GOOD" });

        firstButton.Add(new { type = "click", name = "管理", sub_button = secondButton });

        var input = new { button = firstButton };
        var json = JsonHelper.SerializeObject(input);
        var resultjson = HtmlHelper.HttpPost(uploadUrl, json);
        var output = JsonHelper.DeserializeJsonToObject<span class="hljs-tag">&lt;<span class="hljs-name">T</span>&gt;</span>(resultjson);
        return output;
    }
}</code></span></pre>


<h4 class="wp-block-heading">控制器中调用</h4>


<pre class="wp-block-code"><span><code class="hljs language-php"><span class="hljs-keyword">public</span> ActionResult CreateMenu()
{
    <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">new</span> MenuCreateHandle().DoPost&lt;dynamic&gt;();
    <span class="hljs-keyword">return</span> Json(result);
}</code></span></pre>]]></content:encoded>
					
					<wfw:commentRss>https://www.foxdevelop.com/zh/2026/09/28/09-%e5%85%ac%e4%bc%97%e5%8f%b7%e8%8f%9c%e5%8d%95%e7%ae%a1%e7%90%86/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
