用c#开发微信 (8) 微渠道 - 推广渠道管理系统 3 UI设计及后台处理

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

前面二篇《用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#开发微信 系列汇总

时间: 2024-10-12 19:49:06

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

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

我们可以使用微信的"生成带参数二维码接口"和 "用户管理接口",来实现生成能标识不同推广渠道的二维码,记录分配给不同推广渠道二维码被扫描的信息.这样就可以统计和分析不同推广渠道的推广效果. 上次介绍了<用c#开发微信 (6) 微渠道 - 推广渠道管理系统 1 基础架构搭建>,主要介绍了数据访问层的实现.本文是微渠道的第二篇,主要介绍如下内容: 1. 各个实体具体业务实现 2. 同步微信个人用户信息   下面是详细的实现方法: 1. 各个实体具体业务实现

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

微信平台自带的统计功能太简单,有时我们需要统计有哪些微信个人用户阅读.分享了微信公众号的手机网页,以及微信个人用户访问手机网页的来源:朋友圈分享访问.好友分享消息访问等.本系统实现了手机网页阅读.分享与来源统计及手机网页在朋友圈的传播路径分析. 本系统使用最传统的三层架构.本文是微统计的第一篇,主要介绍如下内容: 1. 数据库设计 2. 数据访问框架层及数据实体层 3. 数据访问层 4. 视图实体定义层   下面是详细实现步骤: 1. 数据库设计 阅读记录 PageNav 分享记录 PageSh

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

在前面几篇文章中,逐步从原有微信的API封装的基础上过渡到微信应用平台管理系统里面,逐步介绍管理系统中的微信数据的界面设计,以及相关的处理操作过程的逻辑和代码,希望从更高一个层次,向大家介绍微信的应用开发过程.本篇主要介绍在管理系统中,如何实现微信用户分组信息的同步操作. 其实微信能够风风火火的原因,主要就是因为有用户信息,所以同步并管理好微信账号的关注用户数据是非常重要的.有了微信用户的数据,你可以和你任何应用系统对接,实现系统-手机客户端的数据整合,还可以对用户进行营销管理,如发送用户感兴趣

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

我们可以使用微信的"生成带参数二维码接口"和 "用户管理接口",来实现生成能标识不同推广渠道的二维码,记录分配给不同推广渠道二维码被扫描的信息.这样就可以统计和分析不同推广渠道的推广效果. 本文是微渠道的第四篇,主要介绍如下内容: 1. 部署 2. 测试   下面是详细的实现方法: 一.部署 1. Entity Framework 错误 如果出现下面的错误: The EntityContainer name must be unique. An EntityCont

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

我们可以使用微信的"生成带参数二维码接口"和 "用户管理接口",来实现生成能标识不同推广渠道的二维码,记录分配给不同推广渠道二维码被扫描的信息.这样就可以统计和分析不同推广渠道的推广效果. 本系统使用最传统的三层架构.本文是微渠道的第一篇,主要介绍如下内容: 1. 数据库设计 2. 数据访问框架层及数据实体层 3. 数据访问层 4. 视图实体定义层   下面是详细实现步骤: 1. 数据库设计 微信用户信息表 WeixinUserInfo 推广渠道类型表 Channe

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

微信营销是一种新型的营销模式,由于微信更重视用户之间的互动,故而这种营销推广不不能盲目地套用微博营销的单纯大量广告推送方式.这种方式在微信营销中的效果非常差,会令用户反感,继而取消去企业或商家的微信公众账号关注.对于企业来说,做微信推广重要的一个方面就是提高用户和公众账号之间的黏度,而微信刮刮卡就是其中最为常见的活动. 下面详细介绍: 一.使用 1. 新建一个刮刮卡的活动: 2. 奖项设置 3. 保存后,在微信里给公众号发一个“刮刮卡”的消息, 就会收到刮刮卡的内容,进入活动后,就可以刮奖了 二

用c#开发微信 (14) 微统计 - 阅读分享统计系统 4 部署测试 (最终效果图)

微信平台自带的统计功能太简单,有时我们需要统计有哪些微信个人用户阅读.分享了微信公众号的手机网页,以及微信个人用户访问手机网页的来源:朋友圈分享访问.好友分享消息访问等.本系统实现了手机网页阅读.分享与来源统计及手机网页在朋友圈的传播路径分析. 本文是微统计的第四篇,主要介绍如下内容:   1. 部署 2. 测试   下面是详细的实现方法: 一.部署 1. Entity Framework 错误 如果出现下面的错误: The EntityContainer name must be unique

用c#开发微信 (17) 微活动 3 投票活动 (文本投票)

前面介绍了微活动<大转盘> 和 <刮刮卡>,这次介绍下微投票,微投票分二种,一种是文本投票, 一种是图片投票.   下面介绍文本投票的详细步骤: 1. 新建文本投票活动     代码实现: <div class="tab-content" > <dl> <dt>投票标题:</dt> <dd> <asp:TextBox runat="server" ID="title&

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

  微信平台自带的统计功能太简单,有时我们需要统计有哪些微信个人用户阅读.分享了微信公众号的手机网页,以及微信个人用户访问手机网页的来源:朋友圈分享访问.好友分享消息访问等.本系统实现了手机网页阅读.分享与来源统计及手机网页在朋友圈的传播路径分析. 本系统使用最传统的三层架构.本文是微统计的第三篇,主要介绍如下内容:   1. 为页面HighCharts画图控件提供数据 2. 接收分享记录信息并保存到数据库 3. 访问记录统计图 4. 阅读统计界面 5. 处理文字请求 前端开发框架使用Boots