接上文 这个函数把用户发来的内容交接给messageHelp来处理 最后返回messageHelp.ReturnMessage
private void Handle(string postStr)
{
messageHelp help = new messageHelp(SqlConnectionString);
string responseContent = help.ReturnMessage(postStr);
HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
HttpContext.Current.Response.Write(responseContent);
}
实现messageHelp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;
public class messageHelp
{
private string mySqlConnectionString;
private WXHelper myWXHelper;
public messageHelp(string SqlConnectionString)
{
mySqlConnectionString = SqlConnectionString;
myWXHelper = new WXHelper(mySqlConnectionString);
}
public string ReturnMessage(string postStr)
{
string responseContent = "";
XmlDocument xmldoc = new XmlDocument();
try
{
xmldoc.Load(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(postStr)));
XmlNode MsgType = xmldoc.SelectSingleNode("/xml/MsgType");
if (MsgType != null)
{
switch (MsgType.InnerText)
{
case "event":
responseContent = EventHandle(xmldoc); //事件处理 关注和取消关注
break;
case "text":
responseContent = TextHandle(xmldoc); //接受文本消息处理
break;
case "image":
responseContent = ImageHandle(xmldoc); //接受图片消息处理
break;
default:
responseContent = DefaultHandle(xmldoc); //接受其他消息处理
break;
}
}
}
catch (Exception ex)
{
DateTime CreateTime = myWXHelper.GetCreateTime(xmldoc);
//开发过程中保留一些出错状况进数据库 很简单的INSERT操作
//myWXHelper.InsertHandleException(ex.Message, CreateTime);
}
return responseContent;
}
public string EventHandle(XmlDocument xmldoc)
{
string responseContent = "";
XmlNode Event = xmldoc.SelectSingleNode("/xml/Event");
if (Event != null)
{
myWXHelper.InsertEvent(xmldoc);
responseContent = myWXHelper.GetEventResponse(xmldoc);
}
return responseContent;
}
public string TextHandle(XmlDocument xmldoc)
{
string responseContent = "";
XmlNode Content = xmldoc.SelectSingleNode("/xml/Content");
if (Content != null)
{
myWXHelper.InsertTextMsg(xmldoc);
//先处理一些特殊功能
responseContent = myWXHelper.GetEspecialTextResponse(xmldoc);
if (string.IsNullOrEmpty(responseContent))
{
//如果不是特殊功能的则处理关键字和其他任意文本的回复
responseContent = myWXHelper.GetTextResponse(xmldoc);
}
}
return responseContent;
}
public string ImageHandle(XmlDocument xmldoc)
{
string responseContent = "";
XmlNode PicUrl = xmldoc.SelectSingleNode("/xml/PicUrl");
if (PicUrl != null)
{
myWXHelper.InsertImageMsg(xmldoc);
responseContent = myWXHelper.GetImageResponse(xmldoc);
}
return responseContent;
}
public string DefaultHandle(XmlDocument xmldoc)
{
string responseContent = "";
return responseContent;
}
}
ReturnMessage中输入的是整个XML文档
MsgType节点表示消息类型
事件、文字、图片消息对应不同的处理
事件包括关注 和 取消关注 需要对用户表进行操作
文字需要保留用户发送的内容
图片需要保留用户发送的图片
GetEspecialTextResponse对某些特定字处理
InsertEvent GetEventResponse InsertTextMsg GetTextResponse InsertImageMsg GetImageResponse需要实现,看字面就能知道干什么用的基本思路 得到XML文档,根据消息类型不同进行处理 文字和图片需要保存到数据库 关注和取消关注修改对应本地用户表 关注还需要回复给用户消息内容 对于特殊的文字 需要优先处理回复 比如发送问号得到菜单发送签到进行签到等功能。
仅示例
public void InsertEvent(XmlDocument xmldoc)
{
XmlNode xnFromUserName = xmldoc.SelectSingleNode("/xml/FromUserName");
string openid = xnFromUserName.InnerText;
DateTime CreateTime = GetCreateTime(xmldoc);
XmlNode xnEvent = xmldoc.SelectSingleNode("/xml/Event");
string Event = xnEvent.InnerText;
using (SqlConnection mySqlConnection = new SqlConnection(mySqlConnectionString))
{
//得到UserID 新用户的话就创建
Int32 UserID = GetUserID(openid);
StrSQL = "INSERT INTO [WX_Event] ([UserID], [CreateTime], [Event]) VALUES (";
StrSQL += "@UserID, @CreateTime, @Event)";
SqlCommand mySqlCommand = new SqlCommand(StrSQL, mySqlConnection);
mySqlCommand.Parameters.AddWithValue("@UserID", UserID);
mySqlCommand.Parameters.AddWithValue("@CreateTime", CreateTime);
mySqlCommand.Parameters.AddWithValue("@Event", Event);
mySqlConnection.Open();
mySqlCommand.ExecuteNonQuery();
mySqlConnection.Close();
}
}
数据库里对WX_Event表设置触发器 unsubscribe时 修改用户状态为未关注 修改用户的取消关注时间 设置用户的重关注标记等 这样当下一次关注时可以知道用记是不是首次关注 还是取消关注后再次关注 因为每个用户对于同一公众号openid不变
public string GetEventResponse(XmlDocument xmldoc)
{
string responseContent = "";
StringBuilder sb = new StringBuilder();
XmlNode ToUserName = xmldoc.SelectSingleNode("/xml/ToUserName");
XmlNode FromUserName = xmldoc.SelectSingleNode("/xml/FromUserName");
string openid = FromUserName.InnerText;
XmlNode xnEvent = xmldoc.SelectSingleNode("/xml/Event");
string Event = xnEvent.InnerText;
Int32 UserID = GetUserID(openid);
if (Event == "subscribe")
{
using (SqlConnection mySqlConnection = new SqlConnection(mySqlConnectionString))
{
mySqlConnection.Open();
string Src = "";
string nickname = "";
SqlCommand mySqlCommand = new SqlCommand("SELECT * FROM [WX_User] WHERE [ID] = @UserID", mySqlConnection);
mySqlCommand.Parameters.AddWithValue("@UserID", UserID);
SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(mySqlCommand);
DataTable myDataTable = new DataTable();
mySqlDataAdapter.Fill(myDataTable);
nickname = Convert.ToString(myDataTable.Rows[0]["nickname"]);
mySqlCommand = new SqlCommand("SELECT COUNT(ID) AS SubscribeOrder FROM [view_WX_User_Subscirbe] WHERE ISNULL(SubscribeTime, '') <> ''", mySqlConnection);
int SubscribeOrder = Convert.ToInt32(mySqlCommand.ExecuteScalar());
if (myDataTable.Rows[0]["UnSubscribeTime"] == DBNull.Value) //首次关注
{
Src = "亲爱的 #nickname, 公众号 感谢您的关注!";
Src += String.Format("\r\n您是第 {0} 位客人", SubscribeOrder);
Src += "\r\n" + dictConstant.GetValue("subscribe", "");
}
else //重新关注
{
Src = "亲爱的 #nickname, 公众号曾经和您小别! 感谢您再次关注!";
Src += String.Format("\r\n您当前是第 {0} 位客人", SubscribeOrder);
Src += "\r\n" + dictConstant.GetValue("resubscribe", "");
}
Src = Src.Replace("#nickname", nickname);
Src = Src.Replace("#openid", openid);
sb.Append(RegexHelper.GetStringBuilderFromLineText(Src));
responseContent = string.Format(ReplyType.Message_Text,
FromUserName.InnerText,
ToUserName.InnerText,
DateTime.Now.Ticks,
sb.ToString()
);
}
}
return responseContent;
}
public class ReplyType
{
/// <summary>
/// 普通文本消息
/// </summary>
public static string Message_Text
{
get
{
return @"<xml>
<ToUserName><![CDATA[{0}]]></ToUserName>
<FromUserName><![CDATA[{1}]]></FromUserName>
<CreateTime>{2}</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[{3}]]></Content>
</xml>";
}
}
}
public Int32 GetUserID(string openid)
{
Int32 Res = -1;
if (!string.IsNullOrWhiteSpace(openid))
{
using (SqlConnection mySqlConnection = new SqlConnection(mySqlConnectionString))
{
SqlCommand mySqlCommand = new SqlCommand("SELECT * FROM [WX_User] WHERE [openid] = @openid", mySqlConnection);
mySqlCommand.Parameters.AddWithValue("@openid", openid);
SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter(mySqlCommand);
DataTable myDataTable = new DataTable();
mySqlDataAdapter.Fill(myDataTable);
if (myDataTable.Rows.Count != 0)
{
Res = Convert.ToInt32(myDataTable.Rows[0]["ID"]);
}
else
{
mySqlConnection.Open();
StrSQL = "BEGIN TRAN; INSERT INTO [WX_User] ([openid]) VALUES (@openid); SELECT IDENT_CURRENT('WX_User'); COMMIT TRAN;";
mySqlCommand = new SqlCommand(StrSQL, mySqlConnection);
mySqlCommand.Parameters.AddWithValue("@openid", openid);
Res = Convert.ToInt32(mySqlCommand.ExecuteScalar());
//该用户不存在于表中 需要 使用Token和Cookie获取关注用户的基本信息
string UserInfoJSON = "";
if (OHWXHelper.GetUserInfoJSON(openid, WXControllerToken, WXControllerCookie, out UserInfoJSON))
{
DataTable dtUserInfo = OHWXHelper.GetUserInfoDataTable(UserInfoJSON);
if (dtUserInfo.Rows.Count == 1)
{
string nickname, city, province, country, headimgurl, subscribe_time, signature;
int sex;
nickname = Convert.ToString(dtUserInfo.Rows[0]["user_name"]);
nickname = nickname.Replace(@"\""", @"""");
nickname = nickname.Replace(@"\/", @"/");
sex = Convert.ToInt16(dtUserInfo.Rows[0]["user_gender"]);
city = Convert.ToString(dtUserInfo.Rows[0]["user_city"]);
province = Convert.ToString(dtUserInfo.Rows[0]["user_province"]);
country = Convert.ToString(dtUserInfo.Rows[0]["user_country"]);
headimgurl = Convert.ToString(dtUserInfo.Rows[0]["user_head_img"]).Replace(@"\/", @"/");
subscribe_time = Convert.ToString(dtUserInfo.Rows[0]["user_create_time"]);
signature = Convert.ToString(dtUserInfo.Rows[0]["user_signature"]);
signature = signature.Replace(@"\""", @"""");
signature = signature.Replace(@"\/", @"/");
StrSQL = "UPDATE [WX_User] SET [openid] = @openid, [nickname] = @nickname, [sex] = @sex, [city] = @city, [province] = @province, [country] = @country, [headimgurl] = @headimgurl, [subscribe_time] = @subscribe_time, [signature] = @signature ";
StrSQL += "WHERE [ID] = @ID";
mySqlCommand = new SqlCommand(StrSQL, mySqlConnection);
mySqlCommand.Parameters.AddWithValue("@openid", openid);
mySqlCommand.Parameters.AddWithValue("@nickname", nickname);
mySqlCommand.Parameters.AddWithValue("@sex", sex);
mySqlCommand.Parameters.AddWithValue("@city", city);
mySqlCommand.Parameters.AddWithValue("@province", province);
mySqlCommand.Parameters.AddWithValue("@country", country);
mySqlCommand.Parameters.AddWithValue("@headimgurl", headimgurl);
mySqlCommand.Parameters.AddWithValue("@subscribe_time", subscribe_time);
mySqlCommand.Parameters.AddWithValue("@signature", signature);
mySqlCommand.Parameters.AddWithValue("@ID", Res);
mySqlCommand.ExecuteNonQuery();
}
else
{
mySqlCommand = new SqlCommand("UPDATE [WX_Controller] SET [InvalidTag] = 1, [InvalidTime] = GETDATE()", mySqlConnection);
mySqlCommand.ExecuteNonQuery();
}
}
else
{
mySqlCommand = new SqlCommand("UPDATE [WX_Controller] SET [InvalidTag] = 1, [InvalidTime] = GETDATE()", mySqlConnection);
mySqlCommand.ExecuteNonQuery();
}
mySqlConnection.Close();
}
}
}
return Res;
}
代码仅示例 从我实际的项目中复制得来 可以在用户关注时回复给用户是第几位关注的用户 同时可以通过控制台的Token和Cookie 根据openid获取用户的一些基本信息昵称 性别 设置的地区 头像链接 微信中设置的签名等等(GetUserInfoJSON)功能实现将JSON直接转换成DataTable
private Dictionary<string, string> dictConstant = new Dictionary<string, string>();
private Dictionary<string, string> dictVariant = new Dictionary<string, string>();
private Dictionary<string, string> dictKeyword = new Dictionary<string, string>();