用c#開發微信 (13) 微統計 - 閱讀分享統計系統 3 UI設計及後臺處理

 

微信平臺自帶的統計功能太簡單,有時咱們須要統計有哪些微信我的用戶閱讀、分享了微信公衆號的手機網頁,以及微信我的用戶訪問手機網頁的來源:朋友圈分享訪問、好友分享消息訪問等。本系統實現了手機網頁閱讀、分享與來源統計及手機網頁在朋友圈的傳播路徑分析。javascript

本系統使用最傳統的三層架構。本文是微統計的第三篇,主要介紹以下內容:css

 

1. 爲頁面HighCharts畫圖控件提供數據html

2. 接收分享記錄信息並保存到數據庫前端

3. 訪問記錄統計圖java

4. 閱讀統計界面jquery

5. 處理文字請求ajax

前端開發框架使用Bootstrap,沒有註明前臺的頁面表示前臺不用顯示任何內容數據庫

1. 爲頁面HighCharts畫圖控件提供數據 Data.aspx

public partial class Data : System.Web.UI.Page
        {
            protected void Page_Load(object sender, EventArgs e)
            {
                string result = "";
                string typeStr = System.Web.HttpContext.Current.Request.QueryString["type"];
                if (!string.IsNullOrEmpty(typeStr))
                {
                    switch (typeStr)
                    {
                        case "navChart": //頁面訪問圖
                            result = JsonConvert.SerializeObject(GetPageNavStatistics());
                            break;
                        case "shareChart": //頁面分享圖
                            result = JsonConvert.SerializeObject(GetPageShareStatistics());
                            break;
                    }
                }
                //將HighCharts繪圖所需的數據返回給頁面
                HttpResponse response = System.Web.HttpContext.Current.Response;
                response.ContentType = "application/json";
                response.Write(result);
                response.End();
            }
 
            /// <summary>
            /// 獲取頁面訪問統計信息
            /// </summary>
            /// <returns></returns>
            private ChartData GetPageNavStatistics()
            {
                //取過去兩天的數據進行統計
                DateTime startTime = DateTime.Now.AddDays(-3);
                DateTime endTime = DateTime.Now.AddDays(1);
                List<PageNavEntity> temp = new PageNavBll().GetPageNavList();
                List<decimal> statistics = new List<decimal>();
                //HighCharts時間軸的起始時間
                ChartData chartData = new ChartData
                {
                    StartYear = startTime.Year,
                    StartDay = startTime.Day,
                    StartMonth = startTime.Month
                };
                //生成按小時統計的數據
                while (startTime < endTime)
                {
                    statistics.Add(temp.FindAll(e => e.VisitTime >= startTime && e.VisitTime < startTime.AddHours(1)).Count());
                    startTime = startTime.AddHours(1);
                }
                chartData.Statistics = statistics.ToArray();
                return chartData;
            }
 
            /// <summary>
            /// 獲取頁面分享統計信息
            /// </summary>
            /// <returns></returns>
            private ChartData GetPageShareStatistics()
            {
                //取過去兩天的數據進行統計
                DateTime startTime = DateTime.Now.AddDays(-3);
                DateTime endTime = DateTime.Now.AddDays(1);
                List<PageShareEntity> temp = new PageShareBll().GetPageShareList();
                List<decimal> statistics = new List<decimal>();
                //HighCharts時間軸的起始時間
                ChartData chartData = new ChartData
                {
                    StartYear = startTime.Year,
                    StartDay = startTime.Day,
                    StartMonth = startTime.Month
                };
                //生成按小時統計的數據
                while (startTime < endTime)
                {
                    statistics.Add(temp.FindAll(e => e.ShareTime >= startTime && e.ShareTime < startTime.AddHours(1)).Count());
                    startTime = startTime.AddHours(1);
                }
                chartData.Statistics = statistics.ToArray();
                return chartData;
            }
        }

2. 接收分享記錄信息並保存到數據庫 Share.aspx

public partial class Share : System.Web.UI.Page
    {
        ILog m_Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
        protected void Page_Load(object sender, EventArgs e)
        {
            string typeStr = Request.QueryString["type"];
 
            m_Log.Info("share type: " + typeStr);
            m_Log.Info("share url: " + Request["url"]);
 
            if (!string.IsNullOrEmpty(typeStr))
            {
                //識別分享類型
                ShareType type = ShareType.Unknown;
                switch (typeStr)
                {
                    case "timeline":
                        type = ShareType.Timeline;
                        break;
                    case "friend":
                        type = ShareType.Friend;
                        break;
                }
                //構造分享記錄
                var pageShare = new PageShareEntity()
                {
                    Id = Guid.NewGuid(),
                    Url = GetOrigenalUrl(Request["url"]),
                    ParentShareOpenId = Request["s"],
                    ShareOpenId = Request["u"],
                    From = type,
                    ShareTime = DateTime.Now
                };
                //保存分享記錄
               bool insertShare = new PageShareBll().InsertPageShare(pageShare);
 
               m_Log.Info("insert share: " + insertShare.ToString());
            }
        }
 
        /// <summary>
        /// 獲取不含統計相關參數的頁面地址
        /// </summary>
        /// <param name="url">網址</param>
        /// <returns>不含統計相關參數的頁面地址</returns>
        private string GetOrigenalUrl(string url)
        {
            url = System.Web.HttpUtility.UrlDecode(url);
            Uri uri = new Uri(url);
            StringBuilder urlBuilder = new StringBuilder();
            //獲取不含QueryString的URL
            urlBuilder.Append("http://")
                .Append(uri.Host)
                .Append(uri.AbsolutePath)
                .Append("?");
            //構造移除統計相關參數的Query
            Dictionary<string, string> queryString = uri.Query.Replace("?", "").Split('&').Where(p => !string.IsNullOrEmpty(p)).ToDictionary(p => p.Split('=')[0], p => p.Split('=')[1].Split('#')[0]);
            foreach (var key in queryString.Keys)
            {
                if (key != "s" && key != "u" && key != "from" && key != "code" && key != "state")
                {
                    urlBuilder.Append(key).Append("=").Append(queryString[key]).Append("&");
                }
            }
            return urlBuilder.ToString();
        }
    }

當發送朋友或朋友圈時保存分享數據。json

 

3. 訪問記錄統計圖 StatisticsPage.aspx

前臺:bootstrap

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="StatisticsPage.aspx.cs" Inherits="Statistics.StatisticsPage" %>
 
<!DOCTYPE html>
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>統計</title>
    <%-- Bootstrap --%>
    <link href="Css/bootstrap.min.css" rel="stylesheet" type="text/css" />
    <script src="Scripts/bootstrap.min.js" type="text/javascript"></script>
    <script src="Scripts/jquery-1.9.1.min.js" type="text/javascript"></script>
    <%-- HighCharts用於圖表顯示 --%>
    <link href="Css/highcharts/charts.css" rel="stylesheet" type="text/css" />
    <script src="Scripts/HighCharts/highcharts.js" type="text/javascript"></script>
    <script src="Scripts/HighCharts/highcharts-more.js" type="text/javascript"></script>
    <script src="Scripts/HighCharts/publiclinecharts.js" type="text/javascript"></script>
</head>
<body>
    <div class="container">
        <div class="row-fluid">
            <div class="span12">
                <h3>訪問記錄</h3>
                <%-- 訪問記錄統計圖 --%>
                <div class="box">
                    <div class="box-content">
                        <div class="row" style="margin-top: 30px; ">
                            <div class="area">
                                <div id="page-nav-chart">
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
                <%-- 訪問記錄列表 --%>
                <div class="maincontentinner1" >
                    <div id="Div12" class="dataTables_wrapper">
                        <table id="page-nav-table" class="table table-bordered responsive dataTable">
                            <%-- 訪問記錄列表列名 --%>
                            <thead>
                                <tr>
                                    <th>頁面地址
                                    </th>
                                    <th>訪問來源
                                    </th>
                                    <th>訪問者openid
                                    </th>
                                    <th>分享自openid
                                    </th>
                                    <th>訪問時間
                                    </th>
                                </tr>
                            </thead>
                            <tbody id="page-nav-table-body">
                                <%-- 一行一行生成訪問記錄列表 --%>
                                <% foreach (Statistics.ViewEntity.PageNavEntity entity in (ViewState["NavList"] as List<Statistics.ViewEntity.PageNavEntity>))
                                   { %>
                                <tr class="gradeX odd">
                                    <td>
                                        <%= entity.Url%>
                                        </td>
                                    <td class=" ">
                                        <%= entity.From.ToString()%>
                                        </td>
                                    <td class=" ">
                                        <%= entity.NavOpenId%>
                                        </td>
                                    <td class=" ">
                                        <%= entity.ShareOpenId%>
                                        </td>
                                    <td class=" ">
                                        <%= entity.VisitTime.ToString()%>
                                        </td>
                                </tr>
                                <% } %>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <script>
        //圖表參數
        var pageNavChartOpts = {
            getStatisticsUrl: 'Data.aspx?type=navChart', //讀取數據的訪問地址
            titletext: "",
            ytext: "",
            startyear: 0,
            startmonth: 0,
            startday: 0,
            lineinterval: 3600 * 1000, //豎線以1小時爲間隔顯示
            pointInterval: 3600 * 1000,//點以1小時爲間隔顯示
            countArray: [],
            formid: "page-nav-chart", //圖表容器ID
            seriesname: "訪問次數",
            unit: "次"
        };
        jQuery(function () {
            //使用HighCharts繪製圖表
            highcharts.extFunction.PreDrawMethod = function (repJson) {
                pageNavChartOpts.startyear = repJson.StartYear;
                pageNavChartOpts.startmonth = repJson.StartMonth;
                pageNavChartOpts.startday = repJson.StartDay;
                highcharts.displayMode = repJson.DisplayMode;
                pageNavChartOpts.lineinterval = repJson.LineInterval;
                pageNavChartOpts.pointInterval = repJson.PointInterval;
            };
            highcharts.init(pageNavChartOpts);
        });
    </script>
</body>
</html>

用HighCharts來圖表顯示數據。

 

後臺:

protected void Page_Load(object sender, EventArgs e)
{
    //傳遞給頁面顯示的記錄列表
    ViewState["NavList"] = new PageNavBll().GetPageNavList();
    ViewState["ShareList"] = new PageShareBll().GetPageShareList();
}

經過業務邏輯層獲取數據。

 

4. 閱讀統計界面 WeixinPageIndex.aspx

前臺:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WeixinPageIndex.aspx.cs" Inherits="Statistics.WeixinPageIndex" %>
 
<!DOCTYPE html>
 
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title></title>
    <script src="Scripts/jquery-1.9.1.min.js"></script>
    <script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script>
</head>
<body>
    <form id="form1" type="post" runat="server">
        <div>
            <%-- 全部的跳轉頁面,加上訪問者與分享者的OpenId --%>
            <a href="WeixinPageSubPage.aspx?u=<%= ViewState["navOpenId"] as string %>&s=<%= ViewState["shareOpenId"] as string %>">WeixinPageSubPage</a>
 
        </div>
    </form>
</body>
</html>
<script>
    var url = location.href;
    alert(url);
    wx.config({
        debug: true, // 開啓調試模式,調用的全部api的返回值會在客戶端alert出來,若要查看傳入的參數,能夠在pc端打開,參數信息會經過log打出,僅在pc端時纔會打印。
        appId: '<%= appID %>', // 必填,公衆號的惟一標識
        timestamp: '<%= timestamp %>', // 必填,生成簽名的時間戳
        nonceStr: '<%= nonceStr %>', // 必填,生成簽名的隨機串
        signature: '<%= signature %>',// 必填,簽名,見附錄1
        // 必填,須要使用的JS接口列表,全部JS接口列表見附錄2
        jsApiList: [
        'onMenuShareAppMessage'
        ]
    });
 
    friendcallback = function (res) {
        var shareUrl = "Share.aspx?type=friend&url=" + encodeURIComponent(url) + "&u=" + "<%= ViewState["navOpenId"] as string %>" + "&s=" + "<%= ViewState["shareOpenId"] as string %>";
 
        //AJAX請求
        $.ajax({
            type: "get",
            url: shareUrl,
            beforeSend: function () {
            },
            success: function () {
            },
            complete: function () {
            },
            error: function () {
            }
        });
    };
 
    wx.ready(function () {
        wx.onMenuShareAppMessage({
            title: '用c#開發微信 系列彙總',
            desc: '網上開發微信開發的教程不少,但c#相對較少。這裏列出了我全部c#開發微信的文章,方便本身隨時查閱。若是可能,我儘可能附上源碼,這樣就能夠直接發佈運行看效果,更好地理解原理。',
            link: url,
            imgUrl: 'http://demo.open.weixin.qq.com/jssdk/images/p2166127561.jpg',
            trigger: function (res) {
            },
            success: function (res) {
                friendcallback(res);
            },
            cancel: function (res) {
            },
            fail: function (res) {
                alert(JSON.stringify(res));
            }
        });
        wx.onMenuShareTimeline({
            title: '用c#開發微信 系列彙總',
            desc: '網上開發微信開發的教程不少,但c#相對較少。這裏列出了我全部c#開發微信的文章,方便本身隨時查閱。若是可能,我儘可能附上源碼,這樣就能夠直接發佈運行看效果,更好地理解原理。',
            link: url,
            imgUrl: 'http://demo.open.weixin.qq.com/jssdk/images/p2166127561.jpg',
            trigger: function (res) {
            },
            success: function (res) {
                friendcallback(res);
            },
            cancel: function (res) {
            },
            fail: function (res) {
                alert(JSON.stringify(res));
            }
        });
    });
 
</script>

利用JS-SDK來獲取分享者,並經過Share頁面來保存分享數據。

 

 

後臺:

public partial class WeixinPageIndex : System.Web.UI.Page
    {
        static ILog m_Log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
 
        public string timestamp = string.Empty;
        public string nonceStr = string.Empty;
        public string signature = string.Empty;
 
        /// <summary>
        /// 從微信公衆平臺獲取的開發者憑據
        /// </summary>
        public readonly string appID = ConfigurationManager.AppSettings["appID"];
        /// <summary>
        /// 從微信公衆平臺獲取的開發者憑據
        /// </summary>
        readonly string appSecret = ConfigurationManager.AppSettings["appSecret"];
 
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                #region 1. Get wx.config
 
                string ticket = string.Empty;
                timestamp = JSSDKHelper.GetTimestamp();
                nonceStr = JSSDKHelper.GetNoncestr();
                JSSDKHelper jssdkhelper = new JSSDKHelper();
 
                try
                {
                    ticket = JsApiTicketContainer.TryGetTicket(appID, appSecret);
                    signature = jssdkhelper.GetSignature(ticket, nonceStr, timestamp, Request.Url.AbsoluteUri.ToString());
                }
                catch (ErrorJsonResultException ex)
                {
                    m_Log.Error("errorcode:" + ex.JsonResult.errcode.ToString() + "  errmsg: " + ex.JsonResult.errmsg, ex);
                }
 
                #endregion
 
                NameValueCollection parameters = System.Web.HttpContext.Current.Request.Params;
 
                m_Log.Info("URL: " + Request.Url.ToString());
 
                //取得連接中的分享者OpenId
                string shareOpenId = parameters["s"];
                //獲取訪問者的OpenId
                string navOpenId = GetNavOpenId();
 
                if (navOpenId != null)
                {
                    NavStatistics(navOpenId, shareOpenId);
                    //傳遞給頁面的訪問者OpenId
                    ViewState["navOpenId"] = navOpenId;
                    //傳遞給頁面的分享者OpenId
                    ViewState["shareOpenId"] = shareOpenId;
                }
 
                m_Log.Info("timestamp: " + timestamp + " nocestr: " + nonceStr + " singnature: " + signature);
                m_Log.Info("nav open id: " + navOpenId + " share open id: " + shareOpenId);
            }
        }
 
        /// <summary>
        /// 記錄頁面訪問
        /// </summary>
        /// <param name="navOpenId">訪問者微信openid</param>
        /// <param name="shareOpenId">當訪問來源爲朋友圈時的分享者微信openid</param>
        private void NavStatistics(string navOpenId, string shareOpenId)
        {
            //獲取訪問來源
            NavFrom fromType = GetNavFromType();
            //構造訪問記錄
            var pageNav = new PageNavEntity()
            {
                Id = Guid.NewGuid(),
                Url = GetOrigenalUrl(),
                NavOpenId = navOpenId,
                ShareOpenId = navOpenId == shareOpenId ? "" : shareOpenId,
                From = fromType,
                VisitTime = DateTime.Now
            };
            //訪問記錄寫入數據庫
            new PageNavBll().InsertPageNav(pageNav);
        }
 
        /// <summary>
        /// 判斷頁面訪問來源類型
        /// </summary>
        /// <returns></returns>
        private static NavFrom GetNavFromType()
        {
            //網址中的參數集合
            NameValueCollection parameters = System.Web.HttpContext.Current.Request.Params;
            string fromStr = parameters["from"]; //發送給朋友、分享到朋友圈的連接會含有from參數
 
            m_Log.Info("from: " + fromStr);
 
            NavFrom fromType;
            if (!Enum.TryParse<NavFrom>(fromStr, true, out fromType)) //經過判斷from參數,識別頁面訪問是來自於發送給朋友的連接仍是分享到朋友圈的連接
            {
                //獲取HTTP訪問頭中的User-Agent參數的值
                string agent = System.Web.HttpContext.Current.Request.Headers["User-Agent"];
                if (agent.Contains(NavFrom.MicroMessenger.ToString())) //判斷頁面是不是在微信內置瀏覽器中打開
                    fromType = NavFrom.MicroMessenger;
                else
                    fromType = NavFrom.Other;
            }
            return fromType;
        }
 
        /// <summary>
        /// 獲取不含統計相關參數的頁面地址
        /// </summary>
        /// <returns>不含統計相關參數的頁面地址</returns>
        private string GetOrigenalUrl()
        {
            StringBuilder urlBuilder = new StringBuilder();
            //獲取不含QueryString的URL
            urlBuilder.Append("http://")
                .Append(System.Web.HttpContext.Current.Request.Url.Host)
                .Append(System.Web.HttpContext.Current.Request.Url.AbsolutePath)
                .Append("?");
            //構造移除統計相關參數的Query
            foreach (var key in System.Web.HttpContext.Current.Request.QueryString.AllKeys)
            {
                if (key != "s" && key != "u" && key != "from" && key != "code" && key != "state")
                {
                    urlBuilder.Append(key).Append("=").Append(System.Web.HttpContext.Current.Request.QueryString[key]).Append("&");
                }
            }
            return urlBuilder.ToString();
        }
 
        /// <summary>
        /// 獲取訪問者openId
        /// </summary>
        private string GetNavOpenId()
        {
            NameValueCollection parameters = System.Web.HttpContext.Current.Request.Params;
            //獲取連接中的openId
            string navOpenId = parameters["u"];
            #region 若是是從微信瀏覽器瀏覽,獲取真實的微信OpenId
            if (!string.IsNullOrEmpty(appID) && !string.IsNullOrEmpty(appSecret))
            {
                string accessSource = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_USER_AGENT"];
 
                if (accessSource.Contains("MicroMessenger")) //若是是從微信打開頁面
                {
                    string[] cookieKeys = new[] { CookieHelper.COOKIE_NAME };
                    Dictionary<string, string> realIdCookie = CookieHelper.GetLoginCookies(cookieKeys); //獲取保存在Cookie中的OpenId
                    //若是Cookie中不存在OpenId,或者連接中的openId與Cookie中的OpenId不一致,連接中的openId爲分享者的OpenId,須要獲取當前用戶的真實OpenId
                    if (NeedGetReadOpenId(parameters, realIdCookie))
                    {
                        if (parameters["code"] == null)
                        {
                            // 先去獲取code,並記錄分享者
                            string snsapi_baseUrl = GoCodeUrl(navOpenId);
                            if (!string.IsNullOrEmpty(snsapi_baseUrl))
                            {
                                CookieHelper.CleanLoginCookie(cookieKeys);
                                //跳轉到微信網頁受權頁面
                                System.Web.HttpContext.Current.Response.Redirect(snsapi_baseUrl, true);
                                System.Web.HttpContext.Current.Response.End();
                                return null;
                            }
                        }
                        else
                        {
                            m_Log.Info("code: " + parameters["code"].ToString());
 
                            OAuthAccessTokenResult tokenResult = GetRealOpenId(parameters["code"].ToString());
                            if (null != tokenResult && !string.IsNullOrEmpty(tokenResult.openid))
                            {
                                m_Log.Info("tokenResult.openid: " + tokenResult.openid);
 
                                navOpenId = tokenResult.openid;
                                // 獲取到的當前訪問者的OpenId保存到cookie裏
                                CookieHelper.CleanLoginCookie(cookieKeys);
                                realIdCookie[CookieHelper.COOKIE_NAME] = tokenResult.openid;
                                CookieHelper.WriteLoginCookies(realIdCookie, DateTime.MinValue);
                            }
                        }
                    }
                }
            }
            #endregion
            return navOpenId;
        }
 
        /// <summary>
        /// 若是Cookie中存在OpenId且連接中的openId與Cookie中的OpenId一致
        /// 則不須要調用網頁受權接口,連接中的openId即爲當前訪問者的真實OpenId
        /// </summary>
        /// <param name="parameters"></param>
        /// <param name="realIdCookie"></param>
        /// <returns></returns>
        private bool NeedGetReadOpenId(NameValueCollection parameters, Dictionary<string, string> realIdCookie)
        {
            string referer = System.Web.HttpContext.Current.Request.ServerVariables["HTTP_REFERER"];
            string openId = null;
            if (realIdCookie != null)
            {
                if (realIdCookie.ContainsKey(CookieHelper.COOKIE_NAME))
                {
                    openId = realIdCookie[CookieHelper.COOKIE_NAME];
                }
            }
 
            m_Log.Info("NeedGetReadOpenId openid: " + openId + " referer: " + referer + " u: " + parameters["u"].ToString());
 
            if (!string.IsNullOrEmpty(referer) && openId == parameters["u"].ToString())
                return false;
            else
                return true;
        }
 
        /// <summary>
        /// 網頁受權接口第一步
        /// 跳轉到獲取code的url
        /// </summary>
        /// <param name="shareOpenId">當訪問來源爲朋友圈時的分享者微信openid</param>
        private string GoCodeUrl(string shareOpenId)
        {
            string url = System.Web.HttpContext.Current.Request.Url.AbsoluteUri + "&s=" + shareOpenId; //添加分享者OpenId
            return OAuthApi.GetAuthorizeUrl(appID, url, "STATE", OAuthScope.snsapi_base);
        }
 
        /// <summary>
        /// 網頁受權接口第二步
        /// 解析code並獲取當前訪問者真正的openId
        /// </summary>
        /// <param name="parameters">url參數</param>
        /// <returns>真正的openId</returns>
        private OAuthAccessTokenResult GetRealOpenId(string code)
        {
            OAuthAccessTokenResult result = new OAuthAccessTokenResult();
            try
            {
                result = OAuthApi.GetAccessToken(appID, appSecret, code);
            }
            catch (Exception ex)
            {
                m_Log.Error(ex.Message, ex);
            }
            return result;
        }
    }

保存訪問者記錄,識別訪問者和分享者。

 

5. 處理文字請求

在CustomMessageHandler裏處理文字請求,詳細的使用方法可參考《用c#開發微信(2)掃描二維碼,用戶受權後獲取用戶基本信息 (源碼下載)》:

public override IResponseMessageBase OnTextRequest(RequestMessageText requestMessage)
        {
            var responseMessage = CreateResponseMessage<ResponseMessageNews>();
            responseMessage.Articles.Add(new Article()
            {
                Title = "首頁",
                Description = "點擊進入首頁",
                PicUrl = "",
                Url = System.Configuration.ConfigurationManager.AppSettings["site"] + "/WeixinPageIndex.aspx?u=" + requestMessage.FromUserName
            });
            return responseMessage;
        }

這裏把訪問者的OpenId帶上,爲了方便識別訪問者和分享者。

 

 

全部界面以下:

image

未完待續!!!

 

 

用c#開發微信 系列彙總
相關文章
相關標籤/搜索