基于vue3 .net core webapi 实现微信分享带缩略图转发功能

一.项目说明

  1. 后端使用Nuget包: skit.flurlhttpclient.wechat.api
  2. 前端使用vue3 + weixin-js-sdk,安装命令: npm install weixin-js-sdk

二.公众号配置

  1. 登录微信开放平台:https://mp.weixin.qq.com/
    找到功能设置,配置Js接口安全域名
    注意:此域名为前端访问地址使用的域名
    在这里插入图片描述
    在这里插入图片描述
    2.配置白名单 用来获取微信 Access token
    在这里插入图片描述
    ****注意如果接口报错信息为ip不在白名单内,请检查服务器是否有两个ip地址,两个ip地址必须都要填入,否则接口无法获取Access token

三.前端实现

1.分享时需调用后端接口,返回微信 WXConfig 配置数据,appId,timestamp,nonceStr,signature
2.jsApiList,为调用微信接口方法名称,具体参考文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/JS-SDK.html
3.要分享的地址必须与微信打开页面的地址相同,否则无法带缩略图分享

const getWxShare = async () => {
		var url = window.location.href;
		let param = {
			url: url
		};
		await GetWXConfig(param).then(res => {
			if (res.data.code == 200 && res.data.data != null) {
				//微信配置
				wx.config({
					debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
					appId: res.data.data.appId, // 必填,公众号的唯一标识
					timestamp: res.data.data.timestamp, // 必填,生成签名的时间戳
					nonceStr: res.data.data.nonceStr, // 必填,生成签名的随机串
					signature: res.data.data.signature, // 必填,签名
					jsApiList: [						
						'updateAppMessageShareData',
						'updateTimelineShareData'
					] // 必填,需要使用的JS接口列表
				});
				
				// wx.error(function(res) {
				// 	console.log(res)
				// });
				
				//转发信息
				var wxtitle = "";
				var wximg = "";
				var wxdescription = "";
					
				//config配置完成后可调用转发
				wx.ready(function() { //需在用户可能点击分享按钮前就先调用
					//自定义“分享给朋友”
					wx.updateAppMessageShareData({
						title: wxtitle, // 分享标题
						desc: wxdescription, // 分享描述
						link: url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
						imgUrl: wximg, // 分享图标
						success: function() {
							// 设置成功
						}
					})
					//自定义“分享到朋友圈”
					wx.updateTimelineShareData({
						title: wxtitle, // 分享标题
						link: url, // 分享链接,该链接域名或路径必须与当前页面对应的公众号JS安全域名一致
						imgUrl: wximg, // 分享图标
						success: function() {
							// 设置成功
						}
					})
				});
			}
		})
	}

四.后端实现

1.Nuget 引用skit.flurlhttpclient.wechat.api
在这里插入图片描述
2.接口实现

/// <summary>
/// 微信
/// </summary>
[Route("WeChatSerivce/api/[controller]")]
[ApiController]
public class WeChatController : ControllerBase
{
    #region 缓存键:Token、Ticket

    /// <summary>
    /// Access token缓存键值
    /// </summary>
    public const string ResCgibinTokenKey = "ResCgibinTokenKey";

    /// <summary>
    /// Ticket缓存键值
    /// </summary>
    public const string TicketKey = "TicketKey";

    #endregion

    #region 依赖注入、初始化微信服务

    private readonly IConfiguration _configuration;
    private readonly WechatApiClient _wechatApiClient;
    private readonly IMemoryCache _memoryCache;

    /// <summary>
    /// 依赖注入、初始化微信服务
    /// </summary>
    /// <param name="configuration">读取配置文件</param>
    /// <param name="memoryCache">缓存</param>
    public WeChatController(IConfiguration configuration, IMemoryCache memoryCache)
    {
        _configuration = configuration;
        _memoryCache = memoryCache;
        var appid = _configuration["Wechat:WechatAppId"];
        var secret = _configuration["Wechat:WechatAppSecret"];

        //初始化微信服务
        WechatApiClientOptions clientOptions = new WechatApiClientOptions()
        {
            AppId = appid,
            AppSecret = secret
        };
        _wechatApiClient = new WechatApiClient(clientOptions);
    }

    #endregion

    #region 校验缓存Token、Tikcet

    /// <summary>
    /// 校验缓存Token、Tikcet
    /// </summary>
    /// <returns></returns>
    [ApiExplorerSettings(IgnoreApi = true)]
    public async Task CheckTokenAndTikcet()
    {
        try
        {
            //获取缓存数据
            var tokendata = _memoryCache.Get<CgibinTokenResponse>(ResCgibinTokenKey)?.AccessToken;
            var ticketdata = _memoryCache.Get<CgibinTicketGetTicketResponse>(TicketKey)?.Ticket;

            //缓存中无数据调用微信接口获取Access token 和 ticket 
            if (string.IsNullOrWhiteSpace(tokendata) || string.IsNullOrWhiteSpace(ticketdata))
            {
                //获取Access token、ticket
                await GetTokenAndTikcet();
            }
        }
        catch
        {
            //获取Access token、ticket
            await GetTokenAndTikcet();
        }
              
    }

    #endregion

    #region 获取Access token、ticket 放到缓存中

    /// <summary>
    /// 获取Access token、ticket 放到缓存
    /// </summary>
    /// <returns></returns>
    [ApiExplorerSettings(IgnoreApi = true)]
    public async Task GetTokenAndTikcet()
    {
        //获取Access token
        var resCgibinToken = await _wechatApiClient.ExecuteCgibinTokenAsync(new CgibinTokenRequest());
        _memoryCache.Set(ResCgibinTokenKey, resCgibinToken, DateTimeOffset.Now.AddHours(1));

        //获取ticket 
        var token = _memoryCache.Get<CgibinTokenResponse>(ResCgibinTokenKey);
        var request = new CgibinTicketGetTicketRequest()
        {
            AccessToken = token?.AccessToken
        };
        var ticket = await _wechatApiClient.ExecuteCgibinTicketGetTicketAsync(request);
        if (ticket.IsSuccessful())
        {
            _memoryCache.Set(TicketKey, ticket, DateTimeOffset.Now.AddHours(1));
        }
    }

    #endregion

    #region 获取微信配置JS-SDK `wx.config`

    /// <summary>
    /// 获取微信配置JS-SDK `wx.config`
    /// </summary>
    /// <param name="url">分享地址</param>
    /// <param>分享地址必须与当前微信访问地址相同,否则分享失败</param>
    /// <returns></returns>
    [HttpPost("GetWXConfig")]
    public async Task<ApiResult<dynamic>> GenConfigPara(string url)
    {
        var res = new ApiResult<dynamic>();

        //获取Access token 放到缓存
        await CheckTokenAndTikcet();

        try
        {
            var response = _memoryCache.Get<CgibinTicketGetTicketResponse>(TicketKey);
            if (!response.IsSuccessful())
            {
                res.success = false;
                res.data = response.ErrorMessage;
                res.code = 400;
                res.message = response.ErrorMessage;
                return await Task.Run(() => res);
            }

            //获取JS-SDK `wx.config` 所需的参数
            var data = _wechatApiClient.GenerateParametersForJSSDKConfig(response.Ticket, url);
            res.success = true;
            res.data = data;
            res.code = 200;
            return await Task.Run(() => res);
        }
        catch (Exception ex)
        {
            res.success = false;
            res.data = ex.Message;
            res.code = 400;
            res.message = ex.Message;

            return await Task.Run(() => res);
        }
    }

    #endregion
    
	/// <summary>
	/// API 返回JSON字符串
	/// </summary>
	/// <typeparam name="T"></typeparam>
	public class ApiResult<T> where T : class
	{
	    /// <summary>
	    /// 是否成功
	    /// </summary>
	    public bool success { get; set; } = true;
	
	    /// <summary>
	    /// 信息
	    /// </summary>
	    public string message { get; set; }
	
	    /// <summary>
	    /// 状态码
	    /// </summary>
	    public int code { get; set; } = 200;
	
	    /// <summary>
	    /// 数据集
	    /// </summary>
	    public T data { get; set; }
	}
}

注意:微信对 access_token、jsapi_ticket 的获取,每天是有次数限制的,其每次获取的有效时长为两小时。因此我们需要将获取到的 access_token 放到系统缓存中,统一进行更新!
在这里插入图片描述
在这里插入图片描述
3.具体操作过程,在微信内打开访问地址,将其网页收藏,然后从收藏处进行转发即可!

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Vue 3.0 和 ASP.NET Core WebAPI 都支持动态路由,实现起来也比较简单。 首先,在 ASP.NET Core WebAPI 中,我们需要在 Startup.cs 中配置路由。可以使用以下代码: ``` app.UseEndpoints(endpoints => { endpoints.MapControllerRoute( name: "default", pattern: "{controller}/{action}/{id?}"); }); ``` 这个配置会将请求转发到对应的控制器和方法中。其中,{controller} 和 {action} 表示控制器和方法名,{id?} 表示可选参数。 接着,在 Vue 3.0 中,我们可以使用 vue-router 实现动态路由。可以使用以下代码: ``` const router = createRouter({ history: createWebHistory(), routes: [ { path: '/:controller/:action/:id?', name: 'dynamic', component: DynamicComponent } ] }) ``` 这个配置会将请求转发到 DynamicComponent 组件中。其中,:controller、:action 和 :id? 表示控制器、方法名和可选参数。 最后,我们可以在 DynamicComponent 组件中调用 ASP.NET Core WebAPI 中的动态路由。可以使用以下代码: ``` axios.get(`/api/${this.$route.params.controller}/${this.$route.params.action}/${this.$route.params.id}`) .then(response => { // 处理响应 }) .catch(error => { // 处理错误 }) ``` 这个代码会发送请求到对应的控制器和方法中,其中,this.$route.params.controller、this.$route.params.action 和 this.$route.params.id 分别对应控制器、方法名和参数。 以上就是 Vue 3.0 和 ASP.NET Core WebAPI 实现动态路由的基本步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南风微凉北城荒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值