我们可以使用微信的“生成带参数二维码接口”和 “用户管理接口”,来实现生成能标识不同推广渠道的二维码,记录分配给不同推广渠道二维码被扫描的信息。这样就可以统计和分析不同推广渠道的推广效果。

前面二篇《用c#开发微信 (6) 微渠道 - 推广渠道管理系统 1 基础架构搭建》, 《用c#开发微信 (7) 微渠道 - 推广渠道管理系统 2 业务逻辑实现》分别介绍了数据访问层和业务逻辑层。 本文是微渠道的第三篇,主要介绍如下内容:

1. 接收二维码扫描事件

2. 推广渠道类型管理

3. 推广渠道管理

4. 推广渠道二维码扫描记录列表

5. 下载渠道二维码

6. 微信用户列表

下面是详细的实现方法:

1. 接收二维码扫描事件

可参考前面的 《用c#开发微信 (4) 基于Senparc.Weixin框架的接收事件推送处理 (源码下载)》,这里就不过多讲解了:

/// <summary>

/// 自定义MessageHandler

/// 把MessageHandler作为基类,重写对应请求的处理方法

/// </summary>

public partial class CustomMessageHandler : MessageHandler<MessageContext<IRequestMessageBase, IResponseMessageBase>>

{

   /// <summary>

   /// 构造函数

   /// </summary>

   /// <param name="inputStream"></param>

   /// <param name="maxRecordCount"></param>

   public CustomMessageHandler(Stream inputStream, int maxRecordCount = 0)

       : base(inputStream, null, maxRecordCount)

   {

       //这里设置仅用于测试,实际开发可以在外部更全局的地方设置,

       //比如MessageHandler<MessageContext>.GlobalWeixinContext.ExpireMinutes = 3。

       WeixinContext.ExpireMinutes = 3;

   }

   public override void OnExecuting()

   {

       //测试MessageContext.StorageData

       if (CurrentMessageContext.StorageData == null)

       {

           CurrentMessageContext.StorageData = 0;

       }

       base.OnExecuting();

   }

   public override void OnExecuted()

   {

       base.OnExecuted();

       CurrentMessageContext.StorageData = ((int)CurrentMessageContext.StorageData) + 1;

   }

   /// <summary>

   /// 处理扫描请求

   /// 用户扫描带场景值二维码时,如果用户已经关注公众号,则微信会将带场景值扫描事件推送给开发者。

   /// </summary>

   /// <returns></returns>

   public override IResponseMessageBase OnEvent_ScanRequest(RequestMessageEvent_Scan requestMessage)

   {

       int sceneId = 0;

       int.TryParse(requestMessage.EventKey, out sceneId);

       if (sceneId > 0)

       {

           new ChannelScanBll().SaveScan(requestMessage.FromUserName, sceneId, ScanType.Scan);

       }

       var responseMessage = CreateResponseMessage<ResponseMessageText>();

       responseMessage.Content = "扫描已记录";

       return responseMessage;

   }

   /// <summary>

   /// 处理关注请求

   /// 用户扫描带场景值二维码时,如果用户还未关注公众号,则用户可以关注公众号,关注后微信会将带场景值关注事件推送给开发者。

   /// </summary>

   /// <returns></returns>

   public override IResponseMessageBase OnEvent_SubscribeRequest(RequestMessageEvent_Subscribe requestMessage)

   {

       if (!string.IsNullOrWhiteSpace(requestMessage.EventKey))

       {

           string sceneIdstr = requestMessage.EventKey.Substring(8);

           int sceneId = 0;

           int.TryParse(sceneIdstr, out sceneId);

           if (sceneId > 0)

           {

               new ChannelScanBll().SaveScan(requestMessage.FromUserName, sceneId, ScanType.Subscribe);

           }

       }

       var responseMessage = CreateResponseMessage<ResponseMessageText>();

       responseMessage.Content = "扫描已记录";

       return responseMessage;

   }

 

   public override IResponseMessageBase DefaultResponseMessage(IRequestMessageBase requestMessage)

   {

       //所有没有被处理的消息会默认返回这里的结果

       var responseMessage = this.CreateResponseMessage<ResponseMessageText>();

       responseMessage.Content = "这条消息来自DefaultResponseMessage。";

       return responseMessage;

   }

}

前端开发框架使用Bootstrap,没有注明前台的页面表示前台不用显示任何内容

2. 推广渠道类型管理

主要是对推广渠道类型的新增、修改、删除及列表显示等

1) 渠道新增、修改页面

前台:

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>修改渠道类型</title>

</head>

<body>

    <form id="Form1" class="form-horizontal" type="post" runat="server">

        <%if (ViewState["channelType"] != null)

          {%>

        <%-- 修改表单 --%>

        <input type="hidden" name="ID" value="<%=(ViewState["channelType"] as ChannelSystem.ViewEntity.ChannelTypeEntity).ID%>" />

        <div class="control-group">

            <label class="control-label" for="Name"><strong>渠道类型名称</strong></label>

            <div class="controls">

                <input type="text" name="Name" value="<%=(ViewState["channelType"] as ChannelSystem.ViewEntity.ChannelTypeEntity).Name%>" />

            </div>

        </div>

        <%}

          else

          {%>

        <%-- 新增表单 --%>

        <div class="control-group">

            <label class="control-label" for="Name"><strong>渠道类型名称</strong></label>

            <div class="controls">

                <input type="text" name="Name" />

            </div>

        </div>

        <%}%>

        <%-- 提交按钮 --%>

        <button class="btn btn-large btn-primary" type="submit">保存</button>

    </form>

</body>

</html>

后台:

/// <summary>

/// 新增或修改渠道类型

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void Page_Load(object sender, EventArgs e)

{

    if (!Page.IsPostBack)

    {

        //修改渠道类型,首先获取渠道类型数据

        int id;

        if (int.TryParse(Request.QueryString["id"], out id))

        {

            ViewState["channelType"] = new ChannelTypeBll().GetEntityById(id);

        }

    }

    else

    {

        //将渠道类型新增或修改的数据保存到数据库

        var entity = new ChannelTypeEntity()

        {

            ID = Request.Form["ID"] == null ? 0 : int.Parse(Request.Form["ID"]),

            Name = Request.Form["Name"]

        };

        new ChannelTypeBll().UpdateOrInsertEntity(entity);

        //回到渠道类型列表页面

        Response.Redirect("ChannelTypeList.aspx");

        Response.End();

    }

}

2) 渠道类型列表页面

前台:

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>渠道类型列表</title>

</head>

<!-- #Bootstrap -->

<link href="Css/bootstrap.min.css" rel="stylesheet" />

<script src="Scripts/bootstrap.min.js"></script>

<!-- #Jquery -->

<script src="Scripts/jquery-1.9.1.min.js"></script>

<body>

    <div class="container">

        <form id="Form1" class="form-horizontal" type="post" runat="server">

            <h2 class="form-signin-heading">渠道类型列表</h2>

            <a class="btnGrayS vm doaddit" href="ChannelTypeEdit.aspx">添加</a> <a class="btnGrayS vm doaddit" href="ChannelList.aspx">渠道列表</a>

            <table id="listTable" class="table table-bordered table-hover dataTable" style="width: auto">

                <thead>

                    <tr>

                        <th style="border-color: #ddd; color: Black">ID

                        </th>

                        <th style="border-color: #ddd; color: Black">渠道类型名称

                        </th>

                        <th style="border-color: #ddd; color: Black">操作

                        </th>

                    </tr>

                </thead>

                <tbody>

                    <% foreach (ChannelSystem.ViewEntity.ChannelTypeEntity channelType in (ViewState["ChannelTypeList"] as List<ChannelSystem.ViewEntity.ChannelTypeEntity>))

                       { %>

                    <tr>

                        <td><%= channelType.ID%>

                                </td>

                        <td><%= channelType.Name%>

                                </td>

                        <td>

                            <p>

                                <a class="btnGrayS vm doaddit" href="ChannelTypeEdit.aspx?id=<%= channelType.ID%>">编辑</a>

                                <a href="javascript:void(0)" data="<%= channelType.ID%>" class="dodelit deleteChannelType">删除</a>

                            </p>

                        </td>

                    </tr>

                    <% } %>

                </tbody>

            </table>

        </form>

    </div>

    <script>

        $(function () {

            $(".deleteChannelType").click(function () {

                if (confirm("确定删除吗?")) {

                    var id = $(this).attr("data");

                    $.ajax({

                        url: "ChannelTypeDelete.aspx?id=" + id,

                        type: "get",

                        success: function (repText) {

                            if (repText && repText == "True") {

                                window.location.reload();

                            } else {

                                alert(repText.ErrorMsg);

                            }

                        },

                        complete: function (xhr, ts) {

                            xhr = null;

                        }

                    });

                }

            });

        });

    </script>

</body>

</html>

后台:

/// <summary>

/// 渠道类型列表

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void Page_Load(object sender, EventArgs e)

{

    //获取渠道类型列表数据

    ViewState["ChannelTypeList"] = new ChannelTypeBll().GetEntities();

}

3) 渠道类型删除页面

后台:

/// <summary>

/// 删除渠道类型

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void Page_Load(object sender, EventArgs e)

{

    //获取渠道类型ID

    int id;

    if (int.TryParse(Request.QueryString["id"], out id))

    {

        //删除渠道类型并返回删除结果

        bool result = new ChannelTypeBll().DeleteEntityById(id);

        Response.Write(result.ToString());

        Response.End();

    }

}

3. 推广渠道管理

主要是对推广渠道的新增、修改、删除及列表显示等

1) 渠道新增、修改页面

前台:

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>修改渠道</title>

</head>

<body>

    <form id="Form1" class="form-horizontal" type="post" runat="server">

        <%if (ViewState["channel"] != null)

          {%>

        <%-- 修改表单 --%>

        <input type="hidden" name="ID" value="<%=(ViewState["channel"] as ChannelSystem.ViewEntity.ChannelEntity).ID%>" />

        <div class="control-group">

            <label class="control-label" for="Name"><strong>渠道名称</strong></label>

            <div class="controls">

                <input type="text" name="Name" value="<%=(ViewState["channel"] as ChannelSystem.ViewEntity.ChannelEntity).Name%>" />

            </div>

        </div>

        <div class="control-group">

            <label class="control-label" for="ChannelTypeId"><strong>所属渠道类型</strong></label>

            <div class="controls">

                <%-- 构造渠道类型下拉框 --%>

                <select name="ChannelTypeId">

                    <% foreach (ChannelSystem.ViewEntity.ChannelTypeEntity channelType in (ViewState["ChannelTypeList"] as List<ChannelSystem.ViewEntity.ChannelTypeEntity>))

                       { %>

                    <%if (channelType.ID == (ViewState["channel"] as ChannelSystem.ViewEntity.ChannelEntity).ChannelTypeId)

                      {%>

                    <%-- 设置渠道类型下拉框初始选中项目 --%>

                    <option value="<%=channelType.ID %>" selected="selected"><%=channelType.Name %></option>

                    <%}

                      else

                      {%>

                    <option value="<%=channelType.ID %>"><%=channelType.Name %></option>

                    <%}%>

                    <% } %>

                </select>

            </div>

        </div>

        <%}

          else

          {%>

        <%-- 新增表单 --%>

        <div class="control-group">

            <label class="control-label" for="Name"><strong>渠道名称</strong></label>

            <div class="controls">

                <input type="text" name="Name" />

            </div>

        </div>

        <div class="control-group">

            <label class="control-label" for="ChannelTypeId"><strong>所属渠道类型</strong></label>

            <div class="controls">

                <%-- 构造渠道类型下拉框 --%>

                <select name="ChannelTypeId">

                    <% foreach (ChannelSystem.ViewEntity.ChannelTypeEntity channelType in (ViewState["ChannelTypeList"] as List<ChannelSystem.ViewEntity.ChannelTypeEntity>))

                       { %>

                    <option value="<%=channelType.ID %>"><%=channelType.Name %></option>

                    <% } %>

                </select>

            </div>

        </div>

        <%}%>

        <%-- 提交按钮 --%>

        <button class="btn btn-large btn-primary" type="submit">保存</button>

    </form>

</body>

</html>

后台:

/// <summary>

/// 新增或修改渠道

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void Page_Load(object sender, EventArgs e)

{

    if (!Page.IsPostBack)

    {

        //获取渠道类型列表数据

        ViewState["ChannelTypeList"] = new ChannelTypeBll().GetEntities();

        //修改渠道,首先获取渠道数据

        int id;

        if (int.TryParse(Request.QueryString["id"], out id))

        {

            ViewState["Channel"] = new ChannelBll().GetEntityById(id);

        }

    }

    else

    {

        //将渠道新增或修改的数据保存到数据库

        var entity = new ChannelEntity()

        {

            ID = Request.Form["ID"] == null ? 0 : int.Parse(Request.Form["ID"]),

            Name = Request.Form["Name"],

            ChannelTypeId = int.Parse(Request.Form["ChannelTypeId"])

        };

        new ChannelBll().UpdateOrInsertEntity(entity);

        //回到渠道列表页面

        Response.Redirect("ChannelList.aspx");

        Response.End();

    }

}

2) 渠道列表页面

前台:

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>渠道类型列表</title>

</head>

<!-- #Bootstrap -->

<link href="Css/bootstrap.min.css" rel="stylesheet" />

<script src="Scripts/bootstrap.min.js"></script>

<!-- #Jquery -->

<script src="Scripts/jquery-1.9.1.min.js"></script>

<body>

    <div class="container">

        <form id="Form1" class="form-horizontal" type="post" runat="server">

            <h2 class="form-signin-heading">渠道类型列表</h2>

            <a class="btnGrayS vm doaddit" href="ChannelTypeEdit.aspx">添加</a> <a class="btnGrayS vm doaddit" href="ChannelList.aspx">渠道列表</a>

            <table id="listTable" class="table table-bordered table-hover dataTable" style="width: auto">

                <thead>

                    <tr>

                        <th style="border-color: #ddd; color: Black">ID

                        </th>

                        <th style="border-color: #ddd; color: Black">渠道类型名称

                        </th>

                        <th style="border-color: #ddd; color: Black">操作

                        </th>

                    </tr>

                </thead>

                <tbody>

                    <% foreach (ChannelSystem.ViewEntity.ChannelTypeEntity channelType in (ViewState["ChannelTypeList"] as List<ChannelSystem.ViewEntity.ChannelTypeEntity>))

                       { %>

                    <tr>

                        <td><%= channelType.ID%>

                                </td>

                        <td><%= channelType.Name%>

                                </td>

                        <td>

                            <p>

                                <a class="btnGrayS vm doaddit" href="ChannelTypeEdit.aspx?id=<%= channelType.ID%>">编辑</a>

                                <a href="javascript:void(0)" data="<%= channelType.ID%>" class="dodelit deleteChannelType">删除</a>

                            </p>

                        </td>

                    </tr>

                    <% } %>

                </tbody>

            </table>

        </form>

    </div>

    <script>

        $(function () {

            $(".deleteChannelType").click(function () {

                if (confirm("确定删除吗?")) {

                    var id = $(this).attr("data");

                    $.ajax({

                        url: "ChannelTypeDelete.aspx?id=" + id,

                        type: "get",

                        success: function (repText) {

                            if (repText && repText == "True") {

                                window.location.reload();

                            } else {

                                alert(repText.ErrorMsg);

                            }

                        },

                        complete: function (xhr, ts) {

                            xhr = null;

                        }

                    });

                }

            });

        });

    </script>

</body>

</html>

后台:

/// <summary>

/// 渠道列表

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void Page_Load(object sender, EventArgs e)

{

    //获取渠道列表数据

    ViewState["ChannelList"] = new ChannelBll().GetEntities();

}

3) 渠道删除页面

后台:

/// <summary>

/// 删除渠道

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void Page_Load(object sender, EventArgs e)

{

    //获取渠道ID

    int id;

    if (int.TryParse(Request.QueryString["id"], out id))

    {

        //删除渠道并返回删除结果

        bool result = new ChannelBll().DeleteEntityById(id);

        Response.Write(result.ToString());

        Response.End();

    }

}

4. 推广渠道二维码扫描记录列表

前台:

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>扫描记录列表</title>

</head>

<!-- #Bootstrap -->

<link href="Css/bootstrap.min.css" rel="stylesheet" />

<script src="Scripts/bootstrap.min.js"></script>

<!-- #Jquery -->

<script src="Scripts/jquery-1.9.1.min.js"></script>

<body>

    <div class="container">

        <form id="Form1" class="form-horizontal" type="post" runat="server">

            <h2 class="form-signin-heading">扫描记录列表</h2>

            <table id="listTable" class="table table-bordered table-hover dataTable" style="width: auto">

                <thead>

                    <tr>

                        <th style="border-color: #ddd; color: Black">ID

                        </th>

                        <th style="border-color: #ddd; color: Black">扫描类型

                        </th>

                        <th style="border-color: #ddd; color: Black">扫描时间

                        </th>

                        <th style="border-color: #ddd; color: Black">所属渠道ID

                        </th>

                        <th style="border-color: #ddd; color: Black">微信用户OpenId

                        </th>

                        <th style="border-color: #ddd; color: Black">头像

                        </th>

                        <th style="border-color: #ddd; color: Black">昵称

                        </th>

                        <th style="border-color: #ddd; color: Black">性别

                        </th>

                        <th style="border-color: #ddd; color: Black">国家

                        </th>

                        <th style="border-color: #ddd; color: Black">省

                        </th>

                        <th style="border-color: #ddd; color: Black">市

                        </th>

                        <th style="border-color: #ddd; color: Black">关注时间

                        </th>

                    </tr>

                </thead>

                <tbody>

                    <% foreach (ChannelSystem.ViewEntity.ChannelScanDisplayEntity channelScanDisplay in (ViewState["ChannelScanDisplayList"] as List<ChannelSystem.ViewEntity.ChannelScanDisplayEntity>))

                       { %>

                    <tr>

                        <td><%= channelScanDisplay.ScanEntity.ID%>

                                </td>

                        <td><%= channelScanDisplay.ScanEntity.ScanType.ToString()%>

                                </td>

                        <td><%= channelScanDisplay.ScanEntity.ScanTime.ToString()%>

                                </td>

                        <td><%= channelScanDisplay.ScanEntity.ChannelId.ToString()%>

                                </td>

                        <td><%= channelScanDisplay.ScanEntity.OpenId%>

                                </td>

                        <td>

                            <img width="50px" src="<%= channelScanDisplay.UserInfoEntity.HeadImgUrl%>" />

                        </td>

                        <td><%= channelScanDisplay.UserInfoEntity.NickName%>

                                </td>

                        <td><%= channelScanDisplay.UserInfoEntity.Sex.ToString()%>

                                </td>

                        <td><%= channelScanDisplay.UserInfoEntity.Country%>

                                </td>

                        <td><%= channelScanDisplay.UserInfoEntity.Province%>

                                </td>

                        <td><%= channelScanDisplay.UserInfoEntity.City%>

                                </td>

                        <td><%= channelScanDisplay.UserInfoEntity.SubscribeTime.ToShortDateString()%>

                                </td>

                    </tr>

                    <% } %>

                </tbody>

            </table>

        </form>

    </div>

</body>

</html>

后台:

/// <summary>

/// 渠道扫描记录列表

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void Page_Load(object sender, EventArgs e)

{

    //获取渠道ID

    int id;

    if (int.TryParse(Request.QueryString["id"], out id))

    {

        //获取渠道扫描记录列表数据

        ViewState["ChannelScanDisplayList"] = new ChannelScanBll().GetChannelScanList(id);

    }

}

5. 下载渠道二维码

后台:

/// <summary>

/// 下载渠道二维码

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

protected void Page_Load(object sender, EventArgs e)

{

    //获取渠道ID

    int id;

    if (int.TryParse(Request.QueryString["id"], out id))

    {

        var entity = new ChannelBll().GetEntityById(id);

        //将数据库中Base64String格式图片转换为Image格式,返回给浏览器

        string base64Image = File.ReadAllText(System.Web.HttpContext.Current.Server.MapPath("~/App_Data/") + entity.Qrcode);

        byte[] arr = Convert.FromBase64String(base64Image);

        MemoryStream ms = new MemoryStream(arr);

        Response.ContentType = "image/jpeg";

        ms.WriteTo(Response.OutputStream);

        Response.End();

    }

}

6. 微信用户列表

前台:

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>微信用户列表</title>

</head>

<!-- #Bootstrap -->

<link href="Css/bootstrap.min.css" rel="stylesheet" />

<script src="Scripts/bootstrap.min.js"></script>

<!-- #Jquery -->

<script src="Scripts/jquery-1.9.1.min.js"></script>

<body>

    <div class="container">

        <form id="Form1" class="form-horizontal" type="post" runat="server">

            <h2 class="form-signin-heading">微信用户列表</h2>

            <table id="listTable" class="table table-bordered table-hover dataTable" style="width: auto">

                <thead>

                    <tr>

                        <th style="border-color: #ddd; color: Black">OpenId

                        </th>

                        <th style="border-color: #ddd; color: Black">头像

                        </th>

                        <th style="border-color: #ddd; color: Black">昵称

                        </th>

                        <th style="border-color: #ddd; color: Black">性别

                        </th>

                        <th style="border-color: #ddd; color: Black">国家

                        </th>

                        <th style="border-color: #ddd; color: Black">省

                        </th>

                        <th style="border-color: #ddd; color: Black">市

                        </th>

                        <th style="border-color: #ddd; color: Black">注册时间

                        </th>

                    </tr>

                </thead>

                <tbody>

                    <% foreach (ChannelSystem.ViewEntity.WeixinUserInfoEntity weixinUserInfo in (ViewState["WeixinUserInfoList"] as List<ChannelSystem.ViewEntity.WeixinUserInfoEntity>))

                       { %>

                    <tr>

                        <td><%= weixinUserInfo.OpenId%>

                                </td>

                        <td>

                            <img width="50px" src="<%= weixinUserInfo.HeadImgUrl%>" />

                        </td>

                        <td><%= weixinUserInfo.NickName%>

                                </td>

                        <td><%= weixinUserInfo.Sex.ToString()%>

                                </td>

                        <td><%= weixinUserInfo.Country%>

                                </td>

                        <td><%= weixinUserInfo.Province%>

                                </td>

                        <td><%= weixinUserInfo.City%>

                                </td>

                        <td><%= weixinUserInfo.SubscribeTime.ToShortDateString()%>

                                </td>

                    </tr>

                    <% } %>

                </tbody>

            </table>

        </form>

    </div>

</body>

</html>

后台:

protected void Page_Load(object sender, EventArgs e)

{

    //获取微信用户列表数据

    ViewState["WeixinUserInfoList"] = new WeixinUserInfoBll().GetEntities();

}

上一篇,讲过同步微信用户的线程只会在这个页面第一次打开时被调用。

同样地,我们也要建一个Index页面作为入口:

private readonly string Token = ConfigurationManager.AppSettings["token"];//与微信公众账号后台的Token设置保持一致,区分大小写。

protected void Page_Load(object sender, EventArgs e)

{

    string signature = Request["signature"];

    string timestamp = Request["timestamp"];

    string nonce = Request["nonce"];

    string echostr = Request["echostr"];

    if (Request.HttpMethod == "GET")

    {

        //get method - 仅在微信后台填写URL验证时触发

        if (CheckSignature.Check(signature, timestamp, nonce, Token))

        {

            WriteContent(echostr); //返回随机字符串则表示验证通过

        }

        else

        {

            WriteContent("failed:" + signature + "," + CheckSignature.GetSignature(timestamp, nonce, Token) + "。" +

                        "如果你在浏览器中看到这句话,说明此地址可以被作为微信公众账号后台的Url,请注意保持Token一致。");

        }

        Response.End();

    }

    else

    {

        //post method - 当有用户想公众账号发送消息时触发

        if (!CheckSignature.Check(signature, timestamp, nonce, Token))

        {

            WriteContent("参数错误!");

            return;

        }

        //设置每个人上下文消息储存的最大数量,防止内存占用过多,如果该参数小于等于0,则不限制

        var maxRecordCount = 10;

        //自定义MessageHandler,对微信请求的详细判断操作都在这里面。

        var messageHandler = new CustomMessageHandler(Request.InputStream, maxRecordCount);

        try

        {

            //测试时可开启此记录,帮助跟踪数据,使用前请确保App_Data文件夹存在,且有读写权限。

            messageHandler.RequestDocument.Save(

                Server.MapPath("~/App_Data/" + DateTime.Now.Ticks + "_Request_" +

                               messageHandler.RequestMessage.FromUserName + ".txt"));

            //执行微信处理过程

            messageHandler.Execute();

            //测试时可开启,帮助跟踪数据

            messageHandler.ResponseDocument.Save(

                Server.MapPath("~/App_Data/" + DateTime.Now.Ticks + "_Response_" +

                               messageHandler.ResponseMessage.ToUserName + ".txt"));

            WriteContent(messageHandler.ResponseDocument.ToString());

            return;

        }

        catch (Exception ex)

        {

            //将程序运行中发生的错误记录到App_Data文件夹

            using (TextWriter tw = new StreamWriter(Server.MapPath("~/App_Data/Error_" + DateTime.Now.Ticks + ".txt")))

            {

                tw.WriteLine(ex.Message);

                tw.WriteLine(ex.InnerException.Message);

                if (messageHandler.ResponseDocument != null)

                {

                    tw.WriteLine(messageHandler.ResponseDocument.ToString());

                }

                tw.Flush();

                tw.Close();

            }

            WriteContent("");

        }

        finally

        {

            Response.End();

        }

    }

}

private void WriteContent(string str)

{

    Response.Output.Write(str);

}

最后整个View就如下图:

未完待续!!!

用c#开发微信 系列汇总

用c#开发微信 (8) 微渠道 - 推广渠道管理系统 3 UI设计及后台处理的更多相关文章

  1. 用c#开发微信 (7) 微渠道 - 推广渠道管理系统 2 业务逻辑实现

    我们可以使用微信的“生成带参数二维码接口”和 “用户管理接口”,来实现生成能标识不同推广渠道的二维码,记录分配给不同推广渠道二维码被扫描的信息.这样就可以统计和分析不同推广渠道的推广效果. 上次介绍了 ...

  2. 用c#开发微信 (11) 微统计 - 阅读分享统计系统 1 基础架构搭建

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

  3. C#开发微信门户及应用(10)--在管理系统中同步微信用户分组信息

    在前面几篇文章中,逐步从原有微信的API封装的基础上过渡到微信应用平台管理系统里面,逐步介绍管理系统中的微信数据的界面设计,以及相关的处理操作过程的逻辑和代码,希望从更高一个层次,向大家介绍微信的应用 ...

  4. 用c#开发微信 (6) 微渠道 - 推广渠道管理系统 1 基础架构搭建

    我们可以使用微信的“生成带参数二维码接口”和 “用户管理接口”,来实现生成能标识不同推广渠道的二维码,记录分配给不同推广渠道二维码被扫描的信息.这样就可以统计和分析不同推广渠道的推广效果. 本系统使用 ...

  5. 用c#开发微信 (9) 微渠道 - 推广渠道管理系统 4 部署测试 (最终效果图)

    我们可以使用微信的“生成带参数二维码接口”和 “用户管理接口”,来实现生成能标识不同推广渠道的二维码,记录分配给不同推广渠道二维码被扫描的信息.这样就可以统计和分析不同推广渠道的推广效果. 本文是微渠 ...

  6. 用c#开发微信 (15) 微活动 1 大转盘

    微信营销是一种新型的营销模式,由于微信更重视用户之间的互动,故而这种营销推广不不能盲目地套用微博营销的单纯大量广告推送方式.这种方式在微信营销中的效果非常差,会令用户反感,继而取消去企业或商家的微信公 ...

  7. 用c#开发微信 (16) 微活动 2 刮刮卡

    微信营销是一种新型的营销模式,由于微信更重视用户之间的互动,故而这种营销推广不不能盲目地套用微博营销的单纯大量广告推送方式.这种方式在微信营销中的效果非常差,会令用户反感,继而取消去企业或商家的微信公 ...

  8. 用c#开发微信 (12) 微统计 - 阅读分享统计系统 2 业务逻辑实现

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

  9. 用c#开发微信 (13) 微统计 - 阅读分享统计系统 3 UI设计及后台处理

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

随机推荐

  1. jQuery MD5加密实现代码

    $(md("你想要加密的字符串")); md5插件下载地址:http://xiazai.jb51.net/201003/yuanma/jquery_md5.rar 下面是我的简单例 ...

  2. linux grep命令详解

    linux grep命令详解 简介 grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来 ...

  3. arpg网页游戏之地图(三)

    地图分块加载类MapEngine,主要包含以下属性: g 地图层graphics,地图将画在上面 buffPixelRange 地图加载范围矩形 viewPort 屏幕视窗 currZoneArr 已 ...

  4. EmptyRecycle() 清空回收站

    //在uses下面引用 function SHEmptyRecycleBinA(Wnd:HWND;str:PChar;WRD:DWORD):Integer;stdcall; external 'SHe ...

  5. vbs获取命令行里的参数

    var args1=WScript.Arguments.Item(0) var args2=WScript.Arguments.Item(1)

  6. SQL Server - select语句练习

    创建表和输入数据 CREATE TABLE STUDENT(SNO VARCHAR(3) NOT NULL,   SNAME VARCHAR(4) NOT NULL,   SSEX VARCHAR(2 ...

  7. NXP开源自动驾驶计算平台Bluebox 打造现实无人汽车

    知名半导体制造商恩智浦NXP已经准备好了自家的自动驾驶计算开源平台Bluebox,将为汽车制造商提供现成的一体化自动 驾驶计算解决方案.专为自动驾驶设备的BlueBox中央计算引擎.不仅能够为无人驾驶 ...

  8. 对需要聚类的数据使用canopy做初步的计算

    K值聚类的时候,需要自己指定cluster的数目. 这个cluster数目一般是通过canopy算法进行预处理来确定的. canopy具体描述可以参考这里. 下面是 golang语言的一个实现(对经纬 ...

  9. (转)SqlBulkCopy批量复制数据

    在.Net1.1中无论是对于批量插入整个DataTable中的所有数据到数据库中,还是进行不同数据源之间的迁移,都不是很方便.而 在.Net2.0中,SQLClient命名空间下增加了几个新类帮助我们 ...

  10. 【Lua】Debian环境下openresty的安装

    OpenResty (也称为 ngx_openresty)是一个全功能的 Web 应用服务器,它打包了标准的 Nginx 核心,很多的常用的第三方模块,以及它们的大多数依赖项. OpenResty 通 ...