Home >WeChat Applet >WeChat Development >WeChat development-Jssdk call sharing example

WeChat development-Jssdk call sharing example

高洛峰
高洛峰Original
2017-02-13 11:36:512457browse

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.IO;
using Newtonsoft.Json;
using System.Net;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Security.Cryptography;

/// <summary>
/// WXJSSDK 的摘要说明
/// </summary>
public class WXJSSDK
{
    private string appId;
    private string appSecret;
    private DataTable DT;

    public WXJSSDK(string appId, string appSecret)
    {
        this.appId = appId;
        this.appSecret = appSecret;
    }

    //得到数据包,返回使用页面  
    public System.Collections.Hashtable getSignPackage()
    {
        string jsapiTicket = getJsApiTicket();
        string url = HttpContext.Current.Request.Url.ToString(); 
        string timestamp = Convert.ToString(ConvertDateTimeInt(DateTime.Now));
        string nonceStr = createNonceStr();


        // 这里参数的顺序要按照 key 值 ASCII 码升序排序  
        string rawstring = "jsapi_ticket=" + jsapiTicket + "&noncestr=" + nonceStr + "&timestamp=" + timestamp + "&url=" + url + "";


        string signature = SHA1_Hash(rawstring);


        System.Collections.Hashtable signPackage = new System.Collections.Hashtable();
        signPackage.Add("appId", appId);
        signPackage.Add("nonceStr", nonceStr);
        signPackage.Add("timestamp", timestamp);
        signPackage.Add("url", url);
        signPackage.Add("signature", signature);
        signPackage.Add("rawString", rawstring);


        return signPackage;
    }


    //创建随机字符串  
    private string createNonceStr()
    {
        int length = 16;
        string chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
        string str = "";
        Random rad = new Random();
        for (int i = 0; i < length; i++)
        {
            str += chars.Substring(rad.Next(0, chars.Length - 1), 1);
        }
        return str;
    }


    //得到ticket 如果文件里时间 超时则重新获取
    //注:jsapi_ticket使用规则(有过期时间)类似access_token, oauth的access_token与基础access_token不同
    private string getJsApiTicket()
    {
        //这里我从数据库读取
        DT = DbSession.Default.FromSql("select jsapi_ticket,ticket_expires from table where ID=1").ToDataTable();
        int expire_time = (int)DT.Rows[0]["ticket_expires"];
        string ticket = DT.Rows[0]["jsapi_ticket"].ToString();
        string accessToken =getAccessToken();//获取系统的全局token 
        if (expire_time < ConvertDateTimeInt(DateTime.Now))
        {
            string url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=" + accessToken + "";
            Jsapi api =JsonConvert.DeserializeObject<Jsapi>(httpGet(url));
            ticket = api.ticket;
            if (ticket != "")
            {
                expire_time = ConvertDateTimeInt(DateTime.Now) + 7000;
                //存入数据库操作
            }
        }
        return ticket;
    }


    ////得到accesstoken 如果文件里时间 超时则重新获取  
    //private string getAccessToken()
    //{
    //    // access_token 应该全局存储与更新,以下代码以写入到文件中做示例
    //    string access_token = "";
    //    string path = HttpContext.Current.Server.MapPath(@"/weixin/access_token.json");
    //    FileStream file = new FileStream(path, FileMode.Open);
    //    var serializer = new DataContractJsonSerializer(typeof(AccToken));
    //    AccToken readJSTicket = (AccToken)serializer.ReadObject(file);
    //    file.Close();
    //    if (readJSTicket.expires_in < ConvertDateTimeInt(DateTime.Now))
    //    {
    //        string url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + appId + "&secret=" + appSecret + "";

    //        AccToken iden = Desrialize<AccToken>(new AccToken(), httpGet(url));

    //        access_token = iden.access_token;
    //        if (access_token != "")
    //        {
    //            iden.expires_in = ConvertDateTimeInt(DateTime.Now) + 7000;
    //            iden.access_token = access_token;

    //            string json = Serialize<AccToken>(iden);
    //            StreamWriterMetod(json, path);
    //        }
    //    }
    //    else
    //    {
    //        access_token = readJSTicket.access_token;
    //    }
    //    return access_token;
    //}


    //发起一个http请球,返回值  
    private string httpGet(string url)
    {
        try
        {
            WebClient MyWebClient = new WebClient();
            MyWebClient.Credentials = CredentialCache.DefaultCredentials;//获取或设置用于向Internet资源的请求进行身份验证的网络凭据  
            Byte[] pageData = MyWebClient.DownloadData(url); //从指定网站下载数据  
            string pageHtml = System.Text.Encoding.Default.GetString(pageData);  //如果获取网站页面采用的是GB2312,则使用这句              

            return pageHtml;
        }


        catch (WebException webEx)
        {
            Console.WriteLine(webEx.Message.ToString());
            return null;
        }
    }


    //SHA1哈希加密算法  
    public string SHA1_Hash(string str_sha1_in)
    {
        SHA1 sha1 = new SHA1CryptoServiceProvider();
        byte[] bytes_sha1_in = System.Text.UTF8Encoding.Default.GetBytes(str_sha1_in);
        byte[] bytes_sha1_out = sha1.ComputeHash(bytes_sha1_in);
        string str_sha1_out = BitConverter.ToString(bytes_sha1_out);
        str_sha1_out = str_sha1_out.Replace("-", "").ToLower();
        return str_sha1_out;
    }


    /// <summary>  
    /// StreamWriter写入文件方法  
    /// </summary>  
    private void StreamWriterMetod(string str, string patch)
    {
        try
        {
            FileStream fsFile = new FileStream(patch, FileMode.OpenOrCreate);
            StreamWriter swWriter = new StreamWriter(fsFile);
            swWriter.WriteLine(str);
            swWriter.Close();
        }
        catch (Exception e)
        {
            throw e;
        }
    }

    /// <summary>  
    /// 将c# DateTime时间格式转换为Unix时间戳格式  
    /// </summary>  
    /// <param name="time">时间</param>  
    /// <returns>double</returns>  
    public int ConvertDateTimeInt(System.DateTime time)
    {
        int intResult = 0;
        System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
        intResult = Convert.ToInt32((time - startTime).TotalSeconds);
        return intResult;
    }
}
//创建Json序列化 及反序列化类目  
#region
//创建JSon类 保存文件 jsapi_ticket.json  
public class JSTicket
{

    public string jsapi_ticket { get; set; }

    public double expire_time { get; set; }
}
//创建 JSon类 保存文件 access_token.json  

public class AccToken
{

    public string access_token { get; set; }

    public double expires_in { get; set; }
}


//创建从微信返回结果的一个类 用于获取ticket  

public class Jsapi
{

    public int errcode { get; set; }

    public string errmsg { get; set; }

    public string ticket { get; set; }

    public string expires_in { get; set; }
}
#endregion

The above is the written class, and then directly call it and output it to js

WXJSSDK jssdk = new WXJSSDK(AppId,AppSecret);
Hashtable hs = jssdk.getSignPackage();
string signature = hs["signature"].ToString();
string signature = hs["signature"].ToString();
string timestamp = hs["timestamp"].ToString();
string nonce = hs["nonceStr"].ToString();

Then js call:

<script type="text/javascript">
            var dataForWeixin = {
                appId: "<%=appid%>",
                MsgImg: "<%=WeChatImg%>",
                TLImg: "<%=WeChatImg%>",
                url: "<%=url%>",
                title: "<%=Title%>",
                desc: "<%=desc%>",
                timestamp: &#39;<%=timestamp%>&#39;,
                nonceStr: &#39;<%=nonce%>&#39;,
                signature: &#39;<%=signature%>&#39;,
                jsApiList: [&#39;onMenuShareTimeline&#39;, &#39;onMenuShareAppMessage&#39;, &#39;onMenuShareQQ&#39;, &#39;onMenuShareWeibo&#39;],
                fakeid: "",
                callback: function () { }
            };
            wx.config({
                debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
                appId: dataForWeixin.appId, // 必填,公众号的唯一标识
                timestamp: dataForWeixin.timestamp, // 必填,生成签名的时间戳
                nonceStr: dataForWeixin.nonceStr, // 必填,生成签名的随机串
                signature: dataForWeixin.signature,// 必填,签名,见附录1
                jsApiList: dataForWeixin.jsApiList  // 必填,需要使用的JS接口列表,所有JS接口列表见附录2
            });
            wx.ready(function () {
                //在此输入各种API
                //分享到朋友圈
                wx.onMenuShareTimeline({
                    title: dataForWeixin.title, // 分享标题
                    link: dataForWeixin.url, // 分享链接
                    imgUrl: dataForWeixin.MsgImg, // 分享图标
                    success: function () {
                        // 用户确认分享后执行的回调函数
                    },
                    cancel: function () {
                        // 用户取消分享后执行的回调函数
                    }
                });
                //分享给朋友
                wx.onMenuShareAppMessage({
                    title: dataForWeixin.title, // 分享标题
                    desc: dataForWeixin.desc, // 分享描述
                    link: dataForWeixin.url, // 分享链接
                    imgUrl: dataForWeixin.TLImg, // 分享图标
                    type: &#39;&#39;, // 分享类型,music、video或link,不填默认为link
                    dataUrl: &#39;&#39;, // 如果type是music或video,则要提供数据链接,默认为空
                    success: function () {
                        // 用户确认分享后执行的回调函数
                    },
                    cancel: function () {
                        // 用户取消分享后执行的回调函数
                    }
                });
                //QQ
                wx.onMenuShareQQ({
                    title: dataForWeixin.title, // 分享标题
                    desc: dataForWeixin.desc, // 分享描述
                    link: dataForWeixin.url, // 分享链接
                    imgUrl: dataForWeixin.MsgImg,// 分享图标
                    success: function () {
                        // 用户确认分享后执行的回调函数
                    },
                    cancel: function () {
                        // 用户取消分享后执行的回调函数
                    }
                });
                //QQ微博
                wx.onMenuShareWeibo({
                    title: dataForWeixin.title, // 分享标题
                    desc: dataForWeixin.desc, // 分享描述
                    link: dataForWeixin.url, // 分享链接
                    imgUrl: dataForWeixin.TLImg, // 分享图标
                    success: function () {
                        // 用户确认分享后执行的回调函数
                    },
                    cancel: function () {
                        // 用户取消分享后执行的回调函数
                    }
                });
                // config信息验证后会执行ready方法,所有接口调用都必须在config接口获得结果之后,config是一个客户端的异步操作,
                //所以如果需要在页面加载时就调用相关接口,则须把相关接口放在ready函数中调用来确保正确执行。对于用户触发时才调用的接口,则可以直接调用,不需要放在ready函数中。
            });
            wx.error(function (res) {
                //alert(res);
                // config信息验证失败会执行error函数,如签名过期导致验证失败,具体错误信息可以打开config的debug模式查看,也可以在返回的res参数中查看,对于SPA可以在这里更新签名。
            });
</script>

微信开发-Jssdk调用分享实例

More WeChat Development-Jssdk call sharing example For related articles, please pay attention to the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn