zoukankan      html  css  js  c++  java
  • 用c#开发微信 (13) 微统计

     

    微信平台自带的统计功能太简单,有时我们需要统计有哪些微信个人用户阅读、分享了微信公众号的手机网页,以及微信个人用户访问手机网页的来源:朋友圈分享访问、好友分享消息访问等。本系统实现了手机网页阅读、分享与来源统计及手机网页在朋友圈的传播路径分析。

    本系统使用最传统的三层架构。本文是微统计的第三篇,主要介绍如下内容:

     

    1. 为页面HighCharts画图控件提供数据

    2. 接收分享记录信息并保存到数据库

    3. 访问记录统计图

    4. 阅读统计界面

    5. 处理文字请求

    前端开发框架使用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();
            }
        }

    当发送朋友或朋友圈时保存分享数据。

     

    3. 访问记录统计图 StatisticsPage.aspx

    前台:

    <%@ 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#开发微信 系列汇总
  • 相关阅读:
    Oracle分页之一:最普通的分页方式
    MSSQL存储过程学习笔记一:关于存储过程
    MSSQL自动备份数据库
    小试JQuery的AutoComplete插件
    利用面向对象的方式来使用JS
    Oracle分页之三:利用PagerView来实现无刷新GridView
    由于 ASP.NET 进程标识对全局程序集缓存没有读权限,因此未能执行请求。错误: 0x80131902
    终端服务器超出最大允许连接数
    从苹果的Siri说起:云搜索与人工智能
    [转]为什么我们程序员难晋升
  • 原文地址:https://www.cnblogs.com/fengwenit/p/4553728.html
Copyright © 2011-2022 走看看