/// <summary>
/// WechartInterface这里使用一般处理程序 这个写好然后在公众号后台配置地址就好了
/// </summary>
public class WechartInterface : IHttpHandler
{
protected string TOKEN = "0000"; //TOKEN 必须跟你在微信公众平台上写的token是一致的
public void ProcessRequest(HttpContext context)
{
//context.Response.ContentType = "text/plain";
context.Response.Clear(); //清除所有之前生成的Response内容
Handlewinxin(context); //进入专业微信处理程序
context.Response.End();
}
public bool IsReusable
{
get
{
return false;
}
}
/// <summary>
///
/// </summary>
/// <param name="content"></param>
public void Handlewinxin(HttpContext context)
{
if (context.Request.HttpMethod.ToUpper() == "GET")
{
// 微信加密签名
string signature = context.Request.QueryString["signature"];
// 时间戳
string timestamp = context.Request.QueryString["timestamp"];
// 随机数
string nonce = context.Request.QueryString["nonce"];
// 随机字符串
string echostr = context.Request.QueryString["echostr"];
if (CheckSignature(signature, timestamp, nonce))
{
CreateMenu(context);
context.Response.Write(echostr);
}
}
else if (context.Request.HttpMethod.ToUpper() == "POST")
{
StreamReader stream = new StreamReader(context.Request.InputStream);
string xml = stream.ReadToEnd();
processRequest(xml, context);
}
}
/// <summary>
/// 验证签名
/// </summary>
/// <param name="signature"></param>
/// <param name="timestamp"></param>
/// <param name="nonce"></param>
/// <returns></returns>
public bool CheckSignature(String signature, String timestamp, String nonce)
{
String[] arr = new String[] { TOKEN, timestamp, nonce };
// 将token、timestamp、nonce三个参数进行字典序排序
Array.Sort<String>(arr);
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.Length; i++)
{
content.Append(arr[i]);
}
String tmpStr = SHA1_Encrypt(content.ToString());
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
return tmpStr != null ? tmpStr.Equals(signature) : false;
}
/// <summary>
/// 使用缺省密钥给字符串加密
/// </summary>
/// <param name="Source_String"></param>
/// <returns></returns>
public static string SHA1_Encrypt(string Source_String)
{
byte[] StrRes = Encoding.Default.GetBytes(Source_String);
HashAlgorithm iSHA = new SHA1CryptoServiceProvider();
StrRes = iSHA.ComputeHash(StrRes);
StringBuilder EnText = new StringBuilder();
foreach (byte iByte in StrRes)
{
EnText.AppendFormat("{0:x2}", iByte);
}
return EnText.ToString();
}
/// <summary>
/// 处理微信发来的请求
/// </summary>
/// <param name="xml"></param>
public void processRequest(String xml, HttpContext context)
{
try
{
LogHelper.Info("微信用户xml:" + xml);
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(new System.IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(xml))); //postStr为微信服务器传过来的xml
WxXmlModel wxXmlModel = new WxXmlModel();
wxXmlModel.ToUserName = xmldoc.SelectSingleNode("/xml/ToUserName").InnerText;
wxXmlModel.FromUserName = xmldoc.SelectSingleNode("/xml/FromUserName").InnerText;
wxXmlModel.CreateTime = xmldoc.SelectSingleNode("/xml/CreateTime").InnerText;
wxXmlModel.MsgType = xmldoc.SelectSingleNode("/xml/MsgType").InnerText;
wxXmlModel.MsgId = xmldoc.SelectSingleNode("/xml/MsgId").InnerText;
switch (wxXmlModel.MsgType)
{
case "text":
wxXmlModel.Content = xmldoc.SelectSingleNode("/xml/Content").InnerText;
WeChatNewsSava(wxXmlModel);
wxXmlModel.Content = Context(wxXmlModel.Content);
HttpContext.Current.Response.Write(WxReplyContext(wxXmlModel));
HttpContext.Current.Response.End();
break;
case "image":
wxXmlModel.PicUrl = xmldoc.SelectSingleNode("/xml/PicUrl").InnerText;
WeChatNewsSava(wxXmlModel);
break;
}
}
catch (Exception ex)
{
LogHelper.Info("微信用户发送消息错误消息:" + ex.Message);//写日志方便调试
}
//HttpContext.Current.Response.Write(wxXmlModel);
//HttpContext.Current.Response.End();
}
/// <summary>
/// 10位时间戳转为C#格式时间
/// </summary>
/// <param name=”timeStamp”></param>
/// <returns></returns>
public DateTime ConvertStringToDateTime(string timeStamp)
{
Int64 begtime = Convert.ToInt64(timeStamp) * 10000000;
DateTime dt_1970 = new DateTime(1970, 1, 1, 8, 0, 0);
long tricks_1970 = dt_1970.Ticks;//1970年1月1日刻度
long time_tricks = tricks_1970 + begtime;//日志日期刻度
DateTime dt = new DateTime(time_tricks);//转化为DateTime
return dt;
}
/// <summary>
/// 回复文本消息
/// </summary>
/// <param name="wxXml"></param>
/// <returns></returns>
public string WxReplyContext(WxXmlModel wxXml)
{
string xml = "<xml>";
xml += "<ToUserName><![CDATA["+ wxXml.FromUserName+ "]]></ToUserName>";
xml += "<FromUserName><![CDATA[" + wxXml.ToUserName + "]]></FromUserName>";
xml += "<CreateTime>" + GetTimestamp() + "</CreateTime>";
xml += "<MsgType><![CDATA[" + wxXml.MsgType + "]]></MsgType>";
xml += "<Content><![CDATA[" + wxXml.Content + "]]></Content>";
xml += "</xml>";
LogHelper.Info("微信回复用户文本:" + xml);
return xml;
}
/// <summary>
/// 将记录保存到数据库
/// </summary>
/// <param name="wxXmlModel"></param>
public void WeChatNewsSava(WxXmlModel wxXmlModel)
{
Dictionary<string, object> keyValuePairs = new Dictionary<string, object>();
keyValuePairs.Add(nameof(wxXmlModel.ToUserName), wxXmlModel.ToUserName);
keyValuePairs.Add(nameof(wxXmlModel.FromUserName), wxXmlModel.FromUserName);
keyValuePairs.Add(nameof(wxXmlModel.CreateTime), ConvertStringToDateTime(wxXmlModel.CreateTime));
keyValuePairs.Add(nameof(wxXmlModel.MsgType), wxXmlModel.MsgType);
keyValuePairs.Add(nameof(wxXmlModel.Content), wxXmlModel.Content);
keyValuePairs.Add(nameof(wxXmlModel.PicUrl), wxXmlModel.PicUrl);
keyValuePairs.Add(nameof(StationId), StationId);
keyValuePairs.Add(nameof(CompanyId), CompanyId);
new BasService().AddRowToDataByORM("tbWeChatNews", ref keyValuePairs);
LogHelper.Info("微信用户发送消添加数据库表:tbWeChatNews");
}
/// <summary>
/// 取当前时间戳十位数
/// </summary>
/// <returns></returns>
public static long GetTimestamp()
{
TimeSpan ts = DateTime.Now.ToUniversalTime() - new DateTime(1970, 1, 1);//ToUniversalTime()转换为标准时区的时间,去掉的话直接就用北京时间
// return (long)ts.TotalMilliseconds; //精确到毫秒
return (long)ts.TotalSeconds;//获取10位
}
//自动回复 这里我是写死的 当然也可以取数据库的数据
public string Context(string str)
{
string strs = "";
switch (str)
{
case "你好":
strs= "您好";
break;
case "客服电话":
strs= "请联系站点客服";
break;
case "客服":
strs= "您要转客服咨询嘛?请输入'人工客服'";
break;
case "人工客服":
strs = "亲,当前客服繁忙,您可以留言您的问题,稍后我们客服会联系您";
break;
default:
strs = "亲,没听懂您的意思哦";
break;
}
return strs;
}
//配置公众号菜单
public void CreateMenu(HttpContext context)
{
string access_token = “”;这个可以通过我前面的文章取获取,有写如何获取
string posturl = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=" + access_token;
string menuStr = "";// " 菜单结构";
using (StreamReader sr = new StreamReader(context.Server.MapPath("/WxMenu.json")))
{
menuStr = sr.ReadToEnd();
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(posturl);
request.Method = "POST";
request.ContentType = "application/json";
using (StreamWriter dataStream = new StreamWriter(request.GetRequestStream()))
{
dataStream.Write(menuStr);
dataStream.Close();
}
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
string encoding = response.ContentEncoding;
if (encoding == null || encoding.Length < 1)
{
encoding = "UTF-8"; //默认编码
}
StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.GetEncoding(encoding));
string retString = reader.ReadToEnd();
}
}
//这个是配置公众号的菜单 这里是用着json数据 当然也可以用数据库或者文本
{
"button": [
{
"name": "外面按钮",
"sub_button": [
{
"type": "view",
"name": "子集按钮1",
"url": "http://www.baidu.com"
}
{
"type": "view",
"name": "子集按钮2",
"url": "http://www.baidu.com"
}
]
},
{
"type": "view",
"name": "父级按钮1",
"url": "http://www.baidu.com"
}
]
}
}
不懂的可以留言版权声明:本文为chenhaishi原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。