和微信用户的沟通少不了,总觉得看起来微信官网后台管理中的会话回复消息有点呆板,所以我这里就自定义了一个会话管理功能,最终效果图如下:

因为我试使用富文本文件CKEDITOR来进行编写,你看到稳中可能会有<P></p>字段,后台获取数据内容时,替换为空字符即可:如下

   string txtcontent = this.txtMessage.Value.ToString().Replace("<p>", "");
            StringBuilder sb = new StringBuilder();
            sb.Append(txtcontent.Replace("</p>\r\n", ""));

在我个人理解,做会话管理,无非就是将用户对话信息(用户发过来的数据,发给用户的数据)存入数据库,根据用户的数据时间和回复用户数据的时间来和当天系统的时间做对比,如果大于多少分钟或者多少个小时就不可以再主动和用户对话,就算我这里是根据微信官网48小时来进行限制的,超过48小时禁用控件,如下图:

废话少说,上代码:需要用到的两个类,数据库也要创建和类相同的名字(至少我试这么做的)

 /// <summary>
/// 微信会话记录类,用户存储会话记录列表
/// </summary>
public class WeixinKeFuInfo
{
public int UId { get; set; }//编号
public string UserOpenId { get; set; }//用户的OpenID
public string UserContent { get; set; }//用户内容
public string CreaterDate { get; set; }//创建时间
} /// <summary>
/// 与微信用户会话的消息记录类
/// </summary>
public class WxMessageInfo
{
public int msgId { get; set; }//消息ID
public string FromUser { get; set; }//发送用户
public string ToUser { get; set; }//接收用户
public string Content { get; set; }//发送内容
public string FaSongDate { get; set; }//发送时间
public string UId { get; set; }//会话用户的UId,微信会话记录类外键
}
  /// <summary>
/// 发送文本。。。。。。。。。。。。。还记得这个方法吗?就是根据用户发送过来的消息类型进行判断后,如果是文本就回复发送此方法内的内容
/// </summary>
/// <param name="requestXML"></param>
private void SendTextCase(RequestXML requestXML)
{       WeixinKeFuService wkfs = new WeixinKeFuService();//自己写的服务类
//根据openId查询数据库会话记录是否存在
WeixinKeFuInfo wkfinfoinfo = wkfs.GetWeixinKeFuInfoByOpenId(requestXML.FromUserName.ToString());
if (wkfinfoinfo != null)
{
//如果存在直接保存消息记录
WxMessageService wms = new WxMessageService();
WxMessageInfo wminfo = new WxMessageInfo();
wminfo.FromUser = requestXML.FromUserName.ToString();
wminfo.ToUser = "我";
wminfo.Content = requestXML.Content.ToString();
wminfo.FaSongDate = System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
wminfo.UId = wkfinfoinfo.UId.ToString();
wms.AddWxMessageInfo(wminfo);
}
else
{
//如果不存在新建会话记录
WeixinKeFuInfo wkfinfo = new WeixinKeFuInfo();
wkfinfo.UserOpenId = requestXML.FromUserName.ToString();
wkfinfo.UserContent = requestXML.Content.ToString();
wkfinfo.CreaterDate = System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
wkfs.AddWeixinKeFuInfo(wkfinfo); string responseContent = FormatTextXML(requestXML.FromUserName, requestXML.ToUserName, "正在接入.请稍候....."); HttpContext.Current.Response.ContentType = "text/xml";
HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
HttpContext.Current.Response.Write(responseContent);
HttpContext.Current.Response.End();
}   }

以上代码实现了数据库的插入,那么取出来,显示的页面,核心代码:WeiXinSessionList.aspx,前台代码如下:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WeiXinSessionList.aspx.cs" Inherits="DQWebSite.Administrator.WeiXinSessionList" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title></title>
<meta http-equiv="refresh" content="60; url=WeiXinSessionList.aspx" />
<link href="css/style.css" rel="Stylesheet" type="text/css" />
<style type="text/css">
.tablestyle { width:1124px; margin:10px auto 10px auto; border:1px solid #ecd9df; text-align:center;
}
th { height:35px;background-image:url('images/th.gif'); background-repeat:repeat-x;
}
tr { height:30px;
}
td {
border-left:1px dotted #a7b5bc;
}
.trcolor { background-color:#ecd9df;
}
tr:hover { cursor:pointer;
}
#FenPage { width:1124px; height:25px; line-height:25px; text-align:center; margin:20px auto 20px auto;
}
.linka { color:#0094ff; cursor:pointer;
}
.fenyebtn {width:60px; height:25px; border:1px solid #ced9df; border-radius:5px; text-align:center; line-height:25px; float:right;
}
.fenyebtn2 { width:60px; height:25px; border:1px solid #ced9df; border-radius:5px; text-align:center; line-height:25px;margin-left:10px;float:right;
}
.toPageIndex { width:60px;height:25px; background-image:url('images/inputbg.gif'); margin-left:10px; background-repeat:repeat-x;border-top:solid 1px #a7b5bc; border-left:solid 1px #a7b5bc; border-right:solid 1px #ced9df; border-bottom:solid 1px #ced9df; text-align:center; float:right;
}
.gotoPagebtn { width:60px; height:25px; border:1px solid #ced9df; border-radius:5px; text-align:center; line-height:25px;margin-left:10px;float:right; background-color:#ced9df;
}
.deletebtn {float:left;width:100px; color:#000; height:25px; background-color:#ced9df; border:1px solid #ced9df; border-radius:5px; text-align:center;
}
#BtnDeleteSelected:hover { cursor:pointer;
}
.publishHuoDong {background-color:#ced9df; border:1px solid #ced9df; border-radius:5px;text-align:center; width:100px; color:#000; height:25px; line-height:25px; float:left;
}
a { color:#08a5e0;
}
.droplist { background-image:url('images/inputbg.gif'); background-repeat:repeat-x; width:120px; height:25px; border:1px solid #ced9df;
}
</style>
<script type="text/javascript"> function EditRoster(piciNumber) {
var url = 'MessageWindow.aspx?id=' + piciNumber; //转向网页的地址;
var name = 'add'; //网页名称,可为空;
var iWidth = 850; //弹出窗口的宽度;
var iHeight = 600; //弹出窗口的高度;
//获得窗口的垂直位置
var iTop = (window.screen.availHeight - 30 - iHeight) / 2;
//获得窗口的水平位置
var iLeft = (window.screen.availWidth - 10 - iWidth) / 2;
window.open(url, name, 'height=' + iHeight + ',,innerHeight=' + iHeight + ',width=' + iWidth + ',innerWidth=' + iWidth + ',top=' + iTop + ',left=' + iLeft + ',status=no,toolbar=no,menubar=no,location=no,resizable=no,scrollbars=0,titlebar=no'); }
</script>
</head>
<body style="background-image:url('images/ygbg.png'); background-repeat:repeat;">
<form id="form1" runat="server">
<div class="place">
<span>位置:</span>
<ul class="placeul">
<li><a href="WelCome.aspx" target="rightFrame">首页</a></li>
<li>微信管理</li>
<li>德桥员工服务中心--会话管理</li>
</ul>
</div>
<div>
<div style="width:1124px;margin:10px auto 0px 20px;">
<font style="color:red;">  根据微信公众平台规定,用户主送发起会话后,48小时之内可与该用户进行无限次会话,超过48小时不能主动会话。</font>
</div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<table class="tablestyle">
<asp:Repeater ID="RepeaterGustBookList" runat="server" OnItemDataBound="RepeaterGustBookList_ItemDataBound">
<HeaderTemplate>
<tr>
<th style="width:50px;"><asp:CheckBox ID="CheckAll" runat="server"
oncheckedchanged="CheckAll_CheckedChanged" /><br /></th>
<th style="width:105px;">openId</th>
<%-- <th style="width:150px;">昵称</th>
<th style="width:50px;">性别</th>--%>
<th style="width:200px;">初始内容</th>
<th style="width:100px;">接入时间</th>
<th style="width:100px;">近期会话</th>
<th style="width:80px;">会话状态</th>
<th style="width:150px;">已过时间</th>
<th style="width:100px;">会话操作</th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<tr style='%#(Container.ItemIndex%2==0)?"#fff":"#ced9ff"%>' >
<td><asp:CheckBox ID="CheckIn" runat="server" /></td>
<td><asp:Label ID="lbUId" runat="server" Visible="false" Text="Label"></asp:Label>
<%# Eval("UserOpenId")%>
</td>
<%-- <td><asp:Label ID="lbNikeName" runat="server" Text="未知"></asp:Label></td>
<td><asp:Label ID="lbSex" runat="server" Text="未知"></asp:Label></td>--%>
<td><%# (Eval("UserContent").ToString().Length>10)?Eval("UserContent").ToString().Substring(0,10)+"..":Eval("UserContent") %></td>
<td><%# Eval("CreaterDate")%></td>
<td><asp:Label ID="lblastDate" runat="server" Text="未知"></asp:Label></td>
<td><asp:Label ID="lbState" runat="server" Text="未知"></asp:Label></td>
<td><asp:Label ID="lbChaoshi" runat="server" Text="未知"></asp:Label></td>
<td><a onclick="EditRoster(<%# Eval("UId") %>);">启动会话</a>  
<%-- <asp:HyperLink ID="HyperLinkNewSession" runat="server">新建</asp:HyperLink> --%>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</table>
<div id="FenPage">
<asp:LinkButton ID="LinkBtnToPage" CssClass="gotoPagebtn" runat="server" OnClick="LinkBtnToPage_Click">确定</asp:LinkButton>
<asp:TextBox ID="txtPageIndex" CssClass="toPageIndex" runat="server"></asp:TextBox> 
<asp:HyperLink ID="lnkLast" runat="server"><span class="fenyebtn2">>>|</span></asp:HyperLink> 
<asp:HyperLink ID="lnkNext" runat="server"><span class="fenyebtn2">></span></asp:HyperLink> 
<asp:HyperLink ID="lnkTop" runat="server"><span class="fenyebtn2"><</span></asp:HyperLink> 
<asp:HyperLink ID="lnkFist" runat="server"><span class="fenyebtn">|<<</span></asp:HyperLink> 
<asp:Button ID="BtnDelete" runat="server" Text="删除选中项" CssClass="deletebtn"
BackColor="ButtonFace" onclick="BtnDelete_Click" />
<span style="float:left;margin-left:20px;">当前第</span>
<span style="float:left; color:red;"><asp:Label ID="lbPageIndex" runat="server" Text=""></asp:Label></span>
<span style="float:left;margin-left:5px;">页/</span>
<span style="float:left;margin-left:5px;">共</span>
<span style="float:left;color:red;"><asp:Label ID="lbCountPage" runat="server" Text=""></asp:Label></span>
<span style="float:left;margin-left:5px;">页</span>
<span style="float:left;margin-left:10px;"><asp:Label ID="lbPageSize" runat="server" Text=""></asp:Label></span>
<span style="float:left;margin-left:10px;">共搜索到 </span>
<span style="float:left;margin-left:5px; color:red;"><asp:Label ID="lbCountData" runat="server" Text=""></asp:Label></span>
<span style="float:left;margin-left:5px;">条记录.</span>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>

WeiXinSessionList.aspx.cs后台代码如下:

PagedDataSource pds = new PagedDataSource();
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
BindGustBookList();
this.DataBind();
UsersInfo user = Session["Users"] as UsersInfo;
if (user != null && user.RolsId == )
{
this.BtnDelete.Enabled = true;
}
else
{
this.BtnDelete.Enabled = false;
}
}
}
private void BindGustBookList()
{ WeixinKeFuService wkf = new WeixinKeFuService();
List<WeixinKeFuInfo> wkflists = wkf.GetAllWeixinKeFuInfoList(); //if (this.DDLState.SelectedValue.Equals("1"))
//{
// lists = gbs.GetAllGustBookListByState();
//}
//else if (this.DDLState.SelectedValue.Equals("2"))
//{
// lists = gbs.GetAllGustBookListByState2();
//}
//else
//{
// lists = gbs.GetAllGustBookList();
//} pds.DataSource = wkflists;
pds.AllowPaging = true;
pds.PageSize = ;//每页显示为20条
int CurrentPage; if (!String.IsNullOrWhiteSpace(this.txtPageIndex.Text.ToString().Trim()))
{ CurrentPage = Convert.ToInt32(this.txtPageIndex.Text.ToString().Trim());
}
else if (Request.QueryString["Page"] != null)
{
CurrentPage = Convert.ToInt32(Request.QueryString["Page"]);
}
else
{
CurrentPage = ;
}
pds.CurrentPageIndex = CurrentPage - ;//当前页的索引就等于当前页码-1;
if (!pds.IsFirstPage)
{
//Request.CurrentExecutionFilePath 为当前请求的虚拟路径
this.lnkTop.NavigateUrl = Request.CurrentExecutionFilePath + "?Page=" + Convert.ToString(CurrentPage - );
this.lnkFist.Enabled = this.lnkTop.Enabled = true;
this.lnkNext.Enabled = this.lnkLast.Enabled = true;
}
else
{
this.lnkFist.Enabled = this.lnkTop.Enabled = false;
this.lnkNext.Enabled = this.lnkLast.Enabled = true;
this.lnkFist.Attributes.Add("style", "color:#ced9df;");
this.lnkTop.Attributes.Add("style", "color:#ced9df;");
this.lnkNext.Attributes.Remove("style");
this.lnkLast.Attributes.Remove("style");
}
if (!pds.IsLastPage)
{
//Request.CurrentExecutionFilePath 为当前请求的虚拟路径
this.lnkNext.NavigateUrl = Request.CurrentExecutionFilePath + "?Page=" + Convert.ToString(CurrentPage + );
this.lnkFist.Enabled = this.lnkTop.Enabled = true;
this.lnkNext.Enabled = this.lnkLast.Enabled = true;
}
else
{
this.lnkNext.Enabled = this.lnkLast.Enabled = false;
this.lnkFist.Enabled = this.lnkTop.Enabled = true;
this.lnkNext.Attributes.Add("style", "color:#ced9df;");
this.lnkLast.Attributes.Add("style", "color:#ced9df;");
this.lnkFist.Attributes.Remove("style");
this.lnkTop.Attributes.Remove("style");
}
this.lnkFist.NavigateUrl = Request.CurrentExecutionFilePath + "?Page=" + Convert.ToString();//跳转至首页
this.lnkLast.NavigateUrl = Request.CurrentExecutionFilePath + "?Page=" + Convert.ToString(pds.PageCount);//跳转至末页 this.RepeaterGustBookList.DataSource = pds;
this.RepeaterGustBookList.DataBind(); this.lbCountData.Text = wkflists.Count.ToString();
this.lbPageIndex.Text = (pds.CurrentPageIndex + ).ToString();
this.lbPageSize.Text = "每页" + pds.PageSize.ToString() + "条记录";
this.lbCountPage.Text = pds.PageCount.ToString();
this.txtPageIndex.Text = (pds.CurrentPageIndex + ).ToString(); if (int.Parse(wkflists.Count.ToString()) <= int.Parse(pds.PageSize.ToString()))
{
this.lnkFist.Visible = this.lnkTop.Visible = this.lnkNext.Visible = this.lnkLast.Visible = this.txtPageIndex.Visible = this.LinkBtnToPage.Visible = false;
}
else
{
this.lnkFist.Visible = this.lnkTop.Visible = this.lnkNext.Visible = this.lnkLast.Visible = this.txtPageIndex.Visible = this.LinkBtnToPage.Visible = true;
} }
/// <summary>
/// 删除选中
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void BtnDelete_Click(object sender, EventArgs e)
{
Boolean bools = false;
foreach (RepeaterItem di in this.RepeaterGustBookList.Items)
{
CheckBox checkIn = (CheckBox)di.FindControl("CheckIn");
if (checkIn.Checked)
{
bools = true;
Label lbGustNo = di.FindControl("lbUId") as Label;
WeixinKeFuService wkf = new WeixinKeFuService();
int num = wkf.DeleteWeixinKeFuInfo(int.Parse(lbGustNo.Text.ToString()));
if (num > )
{
ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "", "alert('删除成功!');location='WeiXinSessionList.aspx'", true);
}
else
{
ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "", "alert('删除失败!');location='WeiXinSessionList.aspx'", true);
}
}
}
if (!bools)
{
ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "", "alert('未选中删除项!');location='WeiXinSessionList.aspx'", true);
}
}
/// <summary>
/// 全选全不选
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void CheckAll_CheckedChanged(object sender, EventArgs e)
{
CheckBox checkAll = (CheckBox)sender;
foreach (RepeaterItem d in this.RepeaterGustBookList.Items)
{
CheckBox checkIn = (CheckBox)d.FindControl("CheckIn");
checkIn.Checked = checkAll.Checked;
}
}
protected void LinkBtnLook_Click(object sender, EventArgs e)
{
BindGustBookList();
}
/// <summary>
/// 绑定事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void RepeaterGustBookList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{ if (e.Item.ItemType == ListItemType.Header)
{
CheckBox checkAll = e.Item.FindControl("CheckAll") as CheckBox;
checkAll.AutoPostBack = true;
}
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
WeixinKeFuInfo wkf = e.Item.DataItem as WeixinKeFuInfo; Label lbUId = e.Item.FindControl("lbUId") as Label;
lbUId.Text = wkf.UId.ToString(); WxMessageService wms = new WxMessageService();
WxMessageInfo wminfo = wms.GetTopLastFaSongDateByUId(lbUId.Text.ToString()); if(wminfo!=null&&!String.IsNullOrWhiteSpace(wminfo.FaSongDate.ToString()))
{
Label lblastDate = e.Item.FindControl("lblastDate") as Label; lblastDate.Text = wminfo.FaSongDate.ToString(); DateTime datesystemss = DateTime.Parse(System.DateTime.Now.ToString());
DateTime lastLoingDatess = DateTime.Parse(lblastDate.Text.ToString()); TimeSpan ts11 = new TimeSpan(datesystemss.Ticks);
TimeSpan ts22 = new TimeSpan(lastLoingDatess.Ticks); TimeSpan ts33 = ts11.Subtract(ts22).Duration(); Label lbState = e.Item.FindControl("lbState") as Label; string chaoshifenzhong = ts33.TotalMinutes.ToString(); if (double.Parse(chaoshifenzhong) <=)
{
lbState.Text = "会话中";
lbState.Attributes.Add("style","color:red;");
}
else
{
lbState.Text = "已结束";
} Label lbChaoshi = e.Item.FindControl("lbChaoshi") as Label; DateTime datesystem = DateTime.Parse(System.DateTime.Now.ToString());
DateTime lastLoingDate = DateTime.Parse(lblastDate.Text.ToString()); TimeSpan ts1 = new TimeSpan(datesystem.Ticks);
TimeSpan ts2 = new TimeSpan(lastLoingDate.Ticks); TimeSpan ts3 = ts1.Subtract(ts2).Duration(); lbChaoshi.Text = ts3.Days.ToString() + "天" + ts3.Hours.ToString() + "小时" + ts3.Minutes.ToString() + "分钟";
} //////根据用户的openId获取用户昵称 //WeiXinServer wxs = new WeiXinServer(); /////从缓存读取accesstoken
//string Access_token = Cache["Access_token"] as string; //if (Access_token == null)
//{
// //如果为空,重新获取
// Access_token = wxs.GetAccessToken(); // //设置缓存的数据7000秒后过期
// Cache.Insert("Access_token", Access_token, null, DateTime.Now.AddSeconds(7000), System.Web.Caching.Cache.NoSlidingExpiration);
//} //string Access_tokento = Access_token.Substring(17, Access_token.Length - 37); //string jsonres = ""; //jsonres = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + Access_tokento + "&openid=" + wkf.UserOpenId; //HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(jsonres);
//myRequest.Method = "GET";
//HttpWebResponse myResponse = (HttpWebResponse)myRequest.GetResponse();
//StreamReader reader = new StreamReader(myResponse.GetResponseStream(), Encoding.UTF8);
//string content = reader.ReadToEnd();
//reader.Close(); ////使用前需药引用Newtonsoft.json.dll文件
//JObject jsonObj = JObject.Parse(content); //Label lbNikeName = e.Item.FindControl("lbNikeName") as Label;
//Label lbSex = e.Item.FindControl("lbSex") as Label;
//lbNikeName.Text = jsonObj["nickname"].ToString();
//if (jsonObj["sex"].ToString().Equals("1"))
//{
// lbSex.Text = "男";
//}
//else
//{
// lbSex.Text = "女";
//} }
}
/// <summary>
/// 输入页码提交跳转
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void LinkBtnToPage_Click(object sender, EventArgs e)
{ if (String.IsNullOrWhiteSpace(this.txtPageIndex.Text.ToString().Trim()))
{
ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "", "alert('页码不能为空!')", true);
this.txtPageIndex.Focus();
return;
}
if (IsNum(this.txtPageIndex.Text.ToString().Trim()))
{
ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "", "alert('页码数只能输入数字!')", true);
this.txtPageIndex.Focus();
this.txtPageIndex.Text = this.lbPageIndex.Text.ToString();
return;
}
if (int.Parse(this.txtPageIndex.Text.ToString().Trim()) > int.Parse(this.lbCountPage.Text.ToString().Trim()))
{
ScriptManager.RegisterClientScriptBlock(this.Page, this.GetType(), "", "alert('所输页数不能大于总页数!')", true);
this.txtPageIndex.Focus();
this.txtPageIndex.Text = this.lbPageIndex.Text.ToString();
return;
} BindGustBookList();
}
/// <summary>
/// 判断是否是数字
/// </summary>
/// <param name="text"></param>
/// <returns></returns>
public static bool IsNum(string text) //
{
for (int i = ; i < text.Length; i++)
{
if (!Char.IsNumber(text, i))
{
return true; //输入的不是数字
}
}
return false; //否则是数字
}

此代码已包含,后台分页功能,仔细研究下,即可使用.

点击开启会话的页面:MessageWindow.aspx如下:

<%@ Page Language="C#" AutoEventWireup="true" ValidateRequest="false" CodeBehind="MessageWindow.aspx.cs" Inherits="DQWebSite.Administrator.MessageWindow" %>

<!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>
<style type="text/css">
.messagestyle { width:100%; height:60px; margin-top:10px;
}
#LinkBtnSubSend { float:left;
}
/*.weixiao{ float:left; background-image:url('images/qqbiaoqing.jpg'); background-repeat:no-repeat; background-position:0px 0px; width:30px; height:28px;
}
.piezui { float:left; background-image:url('images/qqbiaoqing.jpg'); background-repeat:no-repeat; background-position:-31px -0px; width:30px; height:28px;
}
.hanxiao {float:left; background-image:url('images/qqbiaoqing.jpg'); background-repeat:no-repeat; background-position:-0px -62px; width:30px; height:28px;
}
.zhuakuang {float:left; background-image:url('images/qqbiaoqing.jpg'); background-repeat:no-repeat; background-position:-218px -62px; width:28px; height:28px;
}
.shuai {float:left; background-image:url('images/qqbiaoqing.jpg'); background-repeat:no-repeat; background-position:-248px -62px; width:28px; height:28px;
}
.yiwen {float:left; background-image:url('images/qqbiaoqing.jpg'); background-repeat:no-repeat; background-position:-126px -62px; width:28px; height:28px;
}
.liuhan {float:left; background-image:url('images/qqbiaoqing.jpg'); background-repeat:no-repeat; background-position:-404px -30px; width:28px; height:28px;
}*/
a:hover { cursor:pointer;
}
.LinkBtnSubSend { margin-top:5px;
}
</style>
<script type="text/javascript"> function LessThan(oTextArea) { //获得textarea的maxlength属性
var num = oTextArea.getAttribute("maxlength") - oTextArea.value.length; document.getElementById("errmsg").innerHTML = "还可输入的字符数:" + num; //返回文本框字符个数是否符号要求的boolean值
return oTextArea.value.length < oTextArea.getAttribute("maxlength");
}
</script>
<script type="text/javascript" src="../js/jquery-1.7.1.min.js"></script>
<script src="../ckeditor_4.5.4_full2/ckeditor/ckeditor.js"></script>
</head>
<body>
<form id="form1" runat="server">
<div style="height:30px; text-align:left;"> <asp:Label ID="lbduihua1" runat="server" Text="Label"></asp:Label> <span style="color:red;"><asp:Label ID="lbduihuamsg" runat="server" Text="Label"></asp:Label></span> <asp:Label ID="lbduihua2" runat="server" Text="Label"></asp:Label></div>
<div style="height:200px; width:100%; border:2px groove #ced9df; border-top-left-radius:5px; border-top-right-radius:5px; overflow-y:auto;background-image:url('images/ygbg.png'); background-repeat:repeat;">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<ul>
<asp:Repeater ID="RepeaterMessageList" runat="server" OnItemDataBound="RepeaterMessageList_ItemDataBound" >
<ItemTemplate>
<li><span style="color:red;">
<asp:Label ID="lbFromUser" runat="server" Text="Label"></asp:Label> </span>对<span style="color:red;"><%# Eval("ToUser") %></span>说:
<asp:Image ID="Imagelaba" runat="server" />
<br />
<%# Eval("Content") %>  [<%# Eval("FaSongDate") %>]<br />
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
<asp:Timer ID="timeTick" runat="server" Interval="200" OnTick="timeTick_Tick"></asp:Timer>
</ContentTemplate>
</asp:UpdatePanel>
</div>
<textarea id="txtMessage" name="txtMessage" runat="server" class="ckeditor messagestyle" maxlength="200" onkeypress="return LessThan(this);" onchange="return LessThan(this);"></textarea>
<script type="text/javascript">CKEDITOR.replace('<%=txtMessage.ClientID.Replace("_","$") %>');</script>
<div style="height:35px; line-height:35px;">
<asp:LinkButton ID="LinkBtnSubSend" CssClass="LinkBtnSubSend" runat="server" OnClick="LinkBtnSubSend_Click"><div style="background-image:url('images/buttonbg.png'); width:111px; height:35px; line-height:35px; font-weight:bold; text-align:center; float:left; color:#fff;">发送</div></asp:LinkButton>
  <span id="errmsg" style="color:red;" runat="server" >该推送功能直接将信息推送到对方用户微信,谨慎发言</span>
</div>
</form>
</body>
</html>

MessageWindow.aspx.cs的核心代码如下:

protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
if(Request.QueryString["id"]!=null)
{
WeixinKeFuService wkfs = new WeixinKeFuService(); WeixinKeFuInfo wkfinfo = wkfs.GetWeixinKeFuInfoByid(int.Parse(Request.QueryString["id"].ToString()));
this.lbduihuamsg.Text = wkfinfo.UserOpenId.ToString(); this.lbduihua1.Text = "正在于";
this.lbduihua2.Text = "对话中......."; WxMessageService wms = new WxMessageService();
WxMessageInfo wminfo = wms.GetTopLastFaSongDateByUId(wkfinfo.UId.ToString()); if (wminfo != null)
{ DateTime datesystemss = DateTime.Parse(System.DateTime.Now.ToString());
DateTime lastLoingDatess = DateTime.Parse(wminfo.FaSongDate.ToString()); TimeSpan ts11 = new TimeSpan(datesystemss.Ticks);
TimeSpan ts22 = new TimeSpan(lastLoingDatess.Ticks); TimeSpan ts33 = ts11.Subtract(ts22).Duration(); string chaodays = ts33.TotalDays.ToString(); if (double.Parse(chaodays) >=)
{
this.LinkBtnSubSend.Enabled = false;
this.errmsg.InnerText = "会话已结束!超过48小时不能主动推送信息给该用户!";
this.lbduihua1.Text = "已经于";
this.lbduihua2.Text = "失去连接.....除非该用户主动会话才能重新建立连接!";
this.txtMessage.Attributes.Add("readonly","true");
}
} BindMsgList(); this.DataBind();
}
}
} private void BindMsgList()
{
string id = Request.QueryString["id"].ToString(); WxMessageService wms = new WxMessageService(); List<WxMessageInfo> wmlist = wms.GetAllMessageList(id); if(wmlist.Count>)
{
this.RepeaterMessageList.DataSource = wmlist;
this.RepeaterMessageList.DataBind();
} } protected void timeTick_Tick(object sender, EventArgs e)
{
BindMsgList();
}
/// <summary>
/// 推送消息到用户
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
protected void LinkBtnSubSend_Click(object sender, EventArgs e)
{
if(String.IsNullOrWhiteSpace(this.txtMessage.Value.ToString().Trim()))
{
this.errmsg.InnerText = "发送的内容不能为空!";
this.txtMessage.Focus();
return;
}
if (this.txtMessage.Value.ToString().Length < || this.txtMessage.Value.ToString().Length > )
{
this.errmsg.InnerText = "发送内容应在5-200个字符之间!";
this.txtMessage.Focus();
return;
} //如果存在直接保存消息记录
WxMessageService wms = new WxMessageService();
WxMessageInfo wminfo = new WxMessageInfo();
wminfo.FromUser = "我";
wminfo.ToUser = this.lbduihuamsg.Text.ToString();
wminfo.Content = this.txtMessage.Value.ToString().Trim();
wminfo.FaSongDate = System.DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
wminfo.UId = Request.QueryString["id"].ToString();
wms.AddWxMessageInfo(wminfo); WeiXinServer wxs = new WeiXinServer();
string res = ""; ///从缓存读取accesstoken
string Access_token = Cache["Access_token"] as string; if(Access_token==null)
{
//如果为空,重新获取
Access_token = wxs.GetAccessToken(); //设置缓存的数据7000秒后过期
Cache.Insert("Access_token", Access_token, null, DateTime.Now.AddSeconds(), System.Web.Caching.Cache.NoSlidingExpiration);
} string Access_tokento = Access_token.Substring(, Access_token.Length - ); string txtcontent = this.txtMessage.Value.ToString().Replace("<p>", "");
StringBuilder sb = new StringBuilder();
sb.Append(txtcontent.Replace("</p>\r\n", "")); string posturl = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=" + Access_tokento;
string postData = "{\"touser\":\"" + this.lbduihuamsg.Text.ToString() + "\",\"msgtype\":\"text\",\"text\":{\"content\":\"" + sb.ToString() + "\"}}";
res = wxs.GetPage(posturl, postData); //使用前需药引用Newtonsoft.json.dll文件
JObject jsonObj = JObject.Parse(res); ///获取返回结果的正确|true|false
string isright = jsonObj["errcode"].ToString();//
string istrueorfalse = jsonObj["errmsg"].ToString();//ok
if (isright.Equals("") && istrueorfalse.Equals("ok"))
{
this.errmsg.InnerText = "消息推送成功!消息已送达微信用户!";
this.txtMessage.Value = "";
}
else
{
this.errmsg.InnerText = "消息推送失败!消息已保存至数据库!";
}
} protected void RepeaterMessageList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
WxMessageInfo wminfo = e.Item.DataItem as WxMessageInfo; Image Imagelaba = e.Item.FindControl("Imagelaba") as Image; Label lbFromUser = e.Item.FindControl("lbFromUser") as Label; lbFromUser.Text = wminfo.FromUser.ToString(); if (wminfo.FromUser.ToString().Equals("我"))
{
Imagelaba.ImageUrl = "images/fa.gif";
}
else
{
Imagelaba.ImageUrl = "images/shou.gif";
} }
}

以上就是会话管理功能的全部核心代码,仅供参考!另外如果因使用富文本编辑器报下列错误:

A potentially dangerous Request.Form value was detected from the client

解决方法:

用户在页面上提交表单到服务器时,服务器会检测到一些潜在的输入风险,例如使用富文本编辑器控件(RichTextBox、 FreeTextBox、CuteEditor等)编辑的内容中包含有HTML标记或脚本标记,ASP.NET页面会抛出一个"A potentially dangerous Request.Form value was deceted from the client"的异常。这个是ASP.NET页面为了防范页面注入功能的一种保护机制,要取消这种保护,常规的做法是在.aspx文件 的<%@Page %>部分加入ValidateRequest="false"属性。但是从.NET 4.0开始你可能需要多修改一个地方,在网站的web.config文件中加入这行配置:

<system.web>
<compilation debug="true" targetFramework="4.0"/>
<httpRuntime requestValidationMode="2.0"/>
</system.web>

同时,你还需要确保页面上用户输入的部分不会存在任何注入攻击的代码,常用的做法是使用Encode处理。

asp.net微信开发第三篇----自定义会话管理的更多相关文章

  1. asp.net微信开发第八篇----永久素材管理

    除了3天就会失效的临时素材外,开发者有时需要永久保存一些素材,届时就可以通过本接口新增永久素材. 最近更新,永久图片素材新增后,将带有URL返回给开发者,开发者可以在腾讯系域名内使用(腾讯系域名外使用 ...

  2. asp.net微信开发第五篇----用户分组管理

    上一篇已讲解到新建用户分组,移动用户到分组的功能,这一章主要讲解修改分组名称和删除分组 开发者可以使用接口,对公众平台的分组进行查询.创建.修改.删除等操作,也可以使用接口在需要时移动用户到某个分组. ...

  3. asp.net微信开发第四篇----已关注用户管理

    公众号可通过本接口来获取帐号的关注者列表,关注者列表由一串OpenID(加密后的微信号,每个用户对每个公众号的OpenID是唯一的)组成.一次拉取调用最多拉取10000个关注者的OpenID,可以通过 ...

  4. asp.net微信开发第七篇----高级群发(图文)

    上一篇介绍了如何群发文本消息,本篇将介绍如何群发图文信息,上传图文信息所需的素材,界面如下: 我们先看从素材库中获取图文素材的代码,界面: 素材列表,我是使用的repeater控件, 前台代码如下: ...

  5. asp.net微信开发第六篇----高级群发(文本)

    说到高级群发,微信的参考资料http://mp.weixin.qq.com/wiki/14/0c53fac3bdec3906aaa36987b91d64ea.html 首先我们先来讲解一下群发文本信息 ...

  6. asp.net微信开发第十篇----使用百度编辑器编辑图文消息,上传图片、微信视频

    经过几天的资料收集,终于完成了该编辑器的图片上传,视频插入功能,视频插入功能主要借用了该编辑器的插入iframe功能,如原始插件图: 修改后的插件图如下(其中我隐藏掉了一些不需要使用的插件功能): 配 ...

  7. asp.net微信开发第一篇----开发者接入

    在项目的根目录或者特定的文件夹内,创建一个ashx文件(一般处理程序文件),如图 public void ProcessRequest(HttpContext context) { context.R ...

  8. c#微信开发,使用JS-SDK自定义分享功能,分享朋友圈,分享给朋友等

    如果一个后端开发掌握了微信开发,甚至有微信开发上线项目,这在换工作的时候 还是有竞争力的. 微信开发的资料很多,但是用asp.net c#进行微信开发好像比较少,或者资料不够完整. 使用JS-SDK自 ...

  9. asp.net 微信开发(二)

    本节我们主要讲解微信的调试: 前言:平时我们开发项目都是在本地就能进行项目的开发调试,但是在微信上就有难度了,因为微信的数据需要从微信服务器上面拿,所以就需要直接在网站上调试了,接下来就相关的一些个人 ...

随机推荐

  1. codevs 3269 混合背包

    题目描述 Description 背包体积为V ,给出N个物品,每个物品占用体积为Vi,价值为Wi,每个物品要么至多取1件,要么至多取mi件(mi > 1) , 要么数量无限 , 在所装物品总体 ...

  2. Swift中使用构建配置来支持条件编译-b

    在Objective-C中,我们经常使用预处理指令来帮助我们根据不同的平台执行不同的代码,以让我们的代码支持不同的平台,如: 1 2 3 4 5 6 7 8 9 #if TARGET_OS_IPHON ...

  3. 过多if-else分支的优化

    http://www.udpwork.com/item/9294.html 我想谈一谈这个话题是因为我的上一篇博客在ITEye上有一些朋友回复,说if-else过多的分支可以使用switch或者责任链 ...

  4. ExtJS 4 组件详解

    ExtJS 4 的应用界面是由很多小部件组合而成的,这些小部件被称作"组件(Component)",所有组件都是Ext.Component的子类,Ext.Component提供了生 ...

  5. cf C. Hacking Cypher

    http://codeforces.com/contest/490/problem/C 题意:把一个很大的数分成两部分,前一部分可以被a整除,后一部分可以被b整除,如果存在输出这两部分,两部分都不能含 ...

  6. h.264全搜索以及快速全搜索算法

    Full Search 全搜索算法是最简单暴力的一种搜索算法,对搜索范围内的所有像素点都进行匹配对比,选出最合适的运动向量,以下就是一个搜索范围为4的全搜索范围(单个像素点) /*! ******** ...

  7. C51与汇编语言混合编程

    函数内部混合编程 若想在C语言函数内部使用汇编语言,应使用以下Cx51编译器控制命令: #pragma asm ; Assembly code #pragma endasm  功能作用:asm和end ...

  8. 利用Tree命令生成磁盘文件列表

    命令原型:D:/>tree /? 以图形显示驱动器或路径的文件夹结构.TREE [drive:][path] [/F] [/A]/F 显示每个文件夹中文件的名称./A 使用 ASCII 字符,而 ...

  9. Xamarin.Forms本地化多语言

    Forms 右键新建文件夹 Localization 新建文件TranslateExtension.cs namespace Localization { /// <summary> // ...

  10. go官网教程A Tour of Go

    http://tour.golang.org/#1 中文版:http://go-tour-cn.appsp0t.com/#4 package main import ( "fmt" ...