全局注册
所有的 Senparc.Weixin SDK 注册过程都是类似的。
首先,完成所有 Senparc.Weixin SDK 的整体注册代码。在 Program.cs 中加入以下代码:
注册 Senparc.Weixin
说明:
builder.Services.AddMemoryCache()
Senparc.Weixin 支持本机缓存、Redis、Memcached 等多种缓存策略,默认使用本机缓存,此时需要激活本地缓存。
builder.Services.AddSenparcWeixin(builder.Configuration)
用于完成 Senparc.Weixin 的注册。
app.UseSenparcWeixin()
方法用于配置和启用 Senparc.Weixin。
以上代码对于所有的 Senparc.Weixin 下级模块都是相同的,只需要 3 句代码。
本项目参考文件:
公众号注册
在上述代码中的第 17 行委托方法中插入代码,即可完成默认公众号的注册:
register.RegisterMpAccount(weixinSetting, "【盛派网络小助手】公众号");
注册微信公众号
其中,weixinSetting
的值默认来自于 appsettings.json
:
"SenparcWeixinSetting": {
"IsDebug": true,
"Token": "#{Token}#",
"EncodingAESKey": "#{EncodingAESKey}#",
"WeixinAppId": "#{WeixinAppId}#",
"WeixinAppSecret": "#{WeixinAppSecret}#"
}
配置参数
其中,Token
、EncodingAESKey
、WeixinAppId
和 WeixinAppSecret
对应了微信公众号后台的配置参数。
本项目参考文件:
配置完成。
提示:自动注册的信息可通过 Senparc.Weixin.Config.SenparcWeixinSetting
获取。
MessageHandler
用于处理微信公众号对话窗口的消息。
SDK 已经为开发者准备好了所有需要的基础功能,开发者只需要创建一个自定义的子类,补充需要自定义的业务逻辑。
自定义 MessageHandler
当前示例中,我们给自定义的 MessageHandler 取名 CustomMessageHandler
。
CustomMessageHandler.cs 本项目参考文件:
CustomMessageHandler*.cs
中所有演示的重写(override
)方法中,只有 DefaultResponseMessage()
方法是必须重写的,其他所有 OnXxxRequest()
方法都为可选,当用户发送的消息,找不到对应重写方法时,则调用 DefaultResponseMessage()
方法。
MessageHandler 有两种承载方式,使其可以被外部(微信服务器)通过 URL 访问到。分别是中间件方式 (推荐)和 Controller 方式 。两种方式所使用的 CustomMessageHandler
是通用的,因此可以随时切换和共存。
中间件方式承载 MessageHandler
中间件方式是推荐的方式,也是最简化的方式,无需创建任何新文件,只需在 Program.cs
文件所有 Senparc.Weixin 注册代码执行后的下方,引入中间件:
app.UseMessageHandlerForMp("/WeixinAsync", CustomMessageHandler.GenerateMessageHandler, options =>
{
options.AccountSettingFunc = context => Senparc.Weixin.Config.SenparcWeixinSetting;
});
完成后,即可通过Url 域名/WeixinAsync
访问 MessageHandler,设置为公众号后台的消息 URL。
测试 /WeixinAsync
本项目参考文件:
更多中间件方式请参考:《在 .NET Core 2.0/3.0 中使用 MessageHandler 中间件》 (同样适用于 .NET 6.0 及以上)。
Controller 方式承载 MessageHandler
当中间件的方式满足不了需求时,可以使用 Controller 将执行过程“展开”,对每一步执行进行更加精确的控制或干预。
使用 Controller 方式,需要创建 2 个 Action,分别对应微信后台验证(Get 请求),以及真实消息推送(Post 请求)。本项目示例位于 WeixinController.cs 中。
WeixinController.cs 本项目参考文件:
完成后,即可通过Url 域名/Weixin
访问 MessageHandler,设置为公众号后台的消息 URL。
测试 /Weixin
更多 Controller 方式请参考:《了解MessageHandler》 (推荐使用全套异步方法)
完成 Program.cs
文件中的常规注册后,即可在程序的任意地方使用高级接口。
注意:
1、高级接口的配置和 MessageHandler
没有关联,两者可以独立或配合使用。
2、SDK 内几乎所有高级接口的第一个参数同时支持传入 AppId 或 AccessToken,通常名称为 appIdOrAccessToken
,SDK 会根据参数特征自动识别输入的是 AppId 还是 AccessToken,并做区分处理。
使用 AppId 调用接口(推荐)
例如,我们可以在任意一个方法中调用一个高级接口:
var appId = Senparc.Weixin.Config.SenparcWeixinSetting.AppId;
var result = await Senparc.Weixin.MP.AdvancedAPIs.UserApi.GetAsync(appId);//获取关注者 OpenId 信息
appId 参数,必须是已经经过注册的,这样即使 AccessToken 过期,SDK也会全自动处理。如果是未经过注册的 appId,则需要先获取 AccessToken,然后调用接口。
使用 AccessToken 调用接口(不推荐)
var accessToken = Senparc.Weixin.MP.CommonApi.GetTokenAsync(appId, appSecret);//获取 AccessToken
var result = await Senparc.Weixin.MP.AdvancedAPIs.UserApi.GetAsync(accessToken);//获取关注者 OpenId 信息
注意:使用 AccessToken 方式调用接口,无法保证当前 AccessToken 的有效性,因此建议使用前进行有效性校验,并使用 try-catch
方式捕获 AccessToken 不可用的异常,然后进行重试。因此直接使用 AccessToken 调用接口的方式并不推荐在常规情况下使用。
JSSDK 用于提供微信内置浏览器接口的能力,例如转发控制、调用摄像头权限(拍照、视频)、文件上传、关闭窗口、唤起扫码窗口,等等。
要在内置浏览器中只用 JSSDK,分为“服务端获取签名信息”和“网页端配置 JSSDK”两步。
服务端获取签名信息
后端通过 JSSDKHelper.GetJsSdkUiPackageAsync()
方法即可自动获取前端所需的所有 JSSDK 运行所需参数:
public async Task Index()
{
var jssdkUiPackage = await JSSDKHelper.GetJsSdkUiPackageAsync(appId, appSecret, Request.AbsoluteUri());
return View(jssdkUiPackage);
}
本项目参考文件:
网页端配置 JSSDK
后端配置完成的参数,直接在前端 JS 中使用 wx.config
进行设置,例如以下代码将完成在转发网页时自定义转发消息的标题和图片:
wx.config({
debug: false, // 开启调试模式
appId: '@Model.AppId', // 必填,公众号的唯一标识
timestamp: '@Model.Timestamp', // 必填,生成签名的时间戳
nonceStr: '@Model.NonceStr', // 必填,生成签名的随机串
signature: '@Model.Signature',// 必填,签名
jsApiList: [
'checkJsApi',
'onMenuShareTimeline',
'onMenuShareAppMessage'
]
});
wx.error(function (res) {
console.log(res);
alert('验证失败');
});
wx.ready(function () {
var url = 'http://sdk.weixin.senparc.com';
var link = url + '/';
var imgUrl = url + '/images/v2/ewm_01.png';
//转发到朋友圈
wx.onMenuShareTimeline({
title: 'JSSDK朋友圈转发测试',
link: link,
imgUrl: imgUrl,
success: function () {
alert('转发成功!');
},
cancel: function () {
alert('转发失败!');
}
});
//转发给朋友
wx.onMenuShareAppMessage({
title: 'JSSDK朋友圈转发测试',
desc: '转发给朋友',
link: link,
imgUrl: imgUrl,
type: 'link',
dataUrl: '',
success: function () {
alert('转发成功!');
},
cancel: function () {
alert('转发失败!');
}
});
});
提示:在 MVC 中传递 ViewModel 需要在 .cshtml 文件顶部定义:
@model Senparc.Weixin.MP.Helpers.JsSdkUiPackage
本项目参考文件:
更多设置详情请参考:JS-SDK说明文档 。
当你需要在网页上获取用户的 OpenId、头像、昵称等信息的时候,就需要使用 OAuth 2.0 的方式和微信服务器通讯。
更多信息请参考官方文档:opiniones gate.io 。
SDK 已经封装了所有相关的过程,您只需要参考示例进行简单的 3 步配置即可。
第一步:设置登录页面
登录页面中需要设置官方 OAuth 2.0 的请求 URL(称为 AuthorizeUrl ),并带上登录成功后的 returnUrl。
由于微信授权具有两种方式(snsapi_userinfo 和 snsapi_base ,下方代码直接提供了两种获取 AuthorizeUrl 的方式:
public ActionResult Index(string returnUrl)
{
ViewData["returnUrl"] = returnUrl;
//此页面引导用户点击授权
ViewData["UrlUserInfo"] =
OAuthApi.GetAuthorizeUrl(appId,
"http://sdk.weixin.senparc.com/oauth2/UserInfoCallback?returnUrl=" + returnUrl.UrlEncode(),
null, OAuthScope.snsapi_userinfo);//snsapi_userinfo方式回调地址
ViewData["UrlBase"] =
OAuthApi.GetAuthorizeUrl(appId,
"http://sdk.weixin.senparc.com/oauth2/BaseCallback?returnUrl=" + returnUrl.UrlEncode(),
null, OAuthScope.snsapi_base);//snsapi_base方式回调地址
return View();
}
上述 returnUrl
参数一般为跳转到登陆页面之前的 URL,也可以是希望用户完成授权之后跳转到的 URL。
注意:上述的网址和路径需要在公众号后台匹配成你自己服务器的地址(参考文档:网页授权 )。
本项目参考文件:
第二步:前端登录页面设置
登录页面最终的功能是引导用户打开 AuthorizeUrl ,可以直接使用连接的方式:
<!-- snsapi_userinfo方式回调地址 -->
<a href="@ViewData["UrlUserInfo"]">点击这里测试snsapi_userinfo</a>
<!-- snsapi_base方式回调地址 -->
<a href="@ViewData["UrlBase"]">点击这里测试snsapi_userinfo</a>
本项目参考文件:
第三步:配置登陆后回调页面
授权成功后,网页将自动跳转到第一步中设置的回调 URL("http://sdk.weixin.senparc.com/oauth2/UserInfoCallback?returnUrl=" + returnUrl.UrlEncode()
),以 UserInfoCallback 为例:
public ActionResult UserInfoCallback(string code, string returnUrl)
{
if (string.IsNullOrEmpty(code))
{
return Content("您拒绝了授权!");
}
OAuthAccessTokenResult result = null;
//通过,用code换取access_token
try
{
result = OAuthApi.GetAccessToken(appId, appSecret, code);
}
catch (Exception ex)
{
return Content(ex.Message);
}
if (result.errcode != ReturnCode.请求成功)
{
return Content("错误:" + result.errmsg);
}
//下面2个数据也可以自己封装成一个类,储存在数据库中(建议结合缓存)
//如果可以确保安全,可以将access_token存入用户的cookie中,每一个人的access_token是不一样的
HttpContext.Session.SetString("OAuthAccessTokenStartTime", SystemTime.Now.ToString());
HttpContext.Session.SetString("OAuthAccessToken", result.ToJson());
//因为第一步选择的是OAuthScope.snsapi_userinfo,这里可以进一步获取用户详细信息
try
{
if (!string.IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
OAuthUserInfo userInfo = OAuthApi.GetUserInfo(result.access_token, result.openid);
return View(userInfo);
}
catch (ErrorJsonResultException ex)
{
return Content(ex.Message);
}
}
上述代码中,传入的 returnUrl
即第一步 Index()
方法中传入到 AuthorizeUrl 中的 returnUrl
,当所有用户信息获取、保存等操作完成后,借助 returnUrl
跳转到登陆之前的页面,完成整个闭环的登录操作。
本项目参考文件:
使用 Senparc.Weixin,您可以方便快速地开发微信全平台的应用(包括微信公众号、小程序、小游戏、企业号、开放平台、微信支付、JS-SDK、微信硬件/蓝牙,等等)。本项目的 Demo 同样适合初学者进行 .NET 编程学习。
项目自 2012 年开源,2013 年 1 月起正式发布到 GitHub。10 余年来,我们一直保持着项目的持续更新,并将完整的源代码以及设计思想毫无保留地分享给大家,希望有更多的人可以从中受益,理解并传播开源的精神,一同助力中国开源事业!感恩一路上给我们提供帮助的朋友们!
Senparc.Weixin 提供 100% 源码、线上 Sample、文档、图书、视频课程、线上开发者平台、问答平台、QQ / 微信群,以及不定期的线上/线下分享会等各种形式的支持服务,并坚持不间断维护源码,发布新版本。