C#微信公众号开发之微信消息回复及事件类型(四)

 一、相关实体类

 依据接收到的xml消息模板来创建对应的实体类,相关xml消息我就不在这里写了,可以去官方文档中查看https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140453

1.用户发送的xml消息通用节点

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// Message 的摘要说明
/// </summary>
public class BaseMessage
{
    public BaseMessage()
	{
		//
		// TODO: 在此处添加构造函数逻辑
		//
	}
    //开发者微信号
    public string ToUserName;

    //发送方帐号(一个OpenID)
    public string FromUserName;

    //消息创建时间 (整型)
    public string CreateTime;

    //	消息类型,图片为image
    public string MsgType;

}

 2、文本消息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// TextMessage 的摘要说明
/// </summary>
public class TextMessage: BaseMessage
{
    public TextMessage()
	{
	}
    //消息内容
    public string Content;
   
}

3、图片消息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// ImgMessage 的摘要说明
/// </summary>
public class Img:BaseMessage
{
	public Img()
	{
	}
    //图片链接(由系统生成)
    public string PicUrl;

    //图片消息媒体id,可以调用获取临时素材接口拉取数据
    public string MediaId;

    //消息id,64位整型
    public string MsgId;


}

 4、链接

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// LINK 的摘要说明
/// </summary>
public class Link:BaseMessage
{
	public Link()
	{
	}
    //	消息标题
    private string Title;

    //	消息描述
    private string Description;


    //消息链接
    private string Url;

 
    //消息id,64位整型
    private string MsgId;


}

5、语音消息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// VoiceMessage 的摘要说明
/// </summary>
public class Voice:BaseMessage
{
	public Voice()
	{
	}
    //语音消息媒体id,可以调用获取临时素材接口拉取数据。
    public string MediaId;

    /// <summary>
    ///语音格式,如amr,speex等
    /// </summary>
    public string Format;


    //语音识别结果,UTF8编码
    public string Recognition;

    //消息id,64位整型
    public string MsgId;

}

 6、视频消息

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// VideoMessage 的摘要说明
/// </summary>
public class Video:BaseMessage
{
	public Video()
	{
	}
    //视频消息媒体id,可以调用获取临时素材接口拉取数据
    public string MediaId;

    //视频消息缩略图的媒体id,可以调用多媒体文件下载接口拉取数据。
    public string ThumbMediaId;


    //消息id,64位整型
    public string MsgId;

}

 二、消息回复及事件处理

         被动消息回复,包含了文本、语音、图片、视频、音乐、图文,下面值写了前四个和相应的事件如:扫码关注、点击等事件,具体可参考https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140543

using System;
using System.Collections.Generic;
using System.Web;
using System.IO;
using System.Text;
using System.Web.Security;
using System.Xml;

    /// <summary>
    /// 接受/发送消息帮助类
    /// </summary>
    public class MessageHelper
    {
        //返回消息
        public string ReturnMessage(string postStr)
        {
            string responseContent = "";
            XmlDocument xmldoc = new XmlDocument();
            xmldoc.Load(new System.IO.MemoryStream(System.Text.Encoding.GetEncoding("UTF-8").GetBytes(postStr)));
            XmlNode MsgType = xmldoc.SelectSingleNode("/xml/MsgType");
            if (MsgType != null)
            {
                switch (MsgType.InnerText)
                {
                    case "event":
                        responseContent = EventHandle(xmldoc);//事件处理
                        break;
                    case "text":
                        responseContent = CommonApi.ReplayMesg<TextMessage>(xmldoc);//接受文本消息处理
                        break;
                    case "image":
                        responseContent =  CommonApi.ReplayMesg<Img>(xmldoc);//接受图片消息处理
                        break;
                    case "voice":
                        responseContent = CommonApi.ReplayMesg<Voice>(xmldoc);//接受声音消息处理
                        break;
                    case "video":
                        responseContent = CommonApi.ReplayMesg<Video>(xmldoc);//接受视频消息处理(不好用)
                        break;
                    default:
                        break;
                }
            }
            return responseContent;
        }
        //事件
        public string EventHandle(XmlDocument xmldoc)
        {
            string responseContent = "";
            XmlNode Event = xmldoc.SelectSingleNode("/xml/Event");
            XmlNode EventKey = xmldoc.SelectSingleNode("/xml/EventKey");
            XmlNode ToUserName = xmldoc.SelectSingleNode("/xml/ToUserName");
            XmlNode FromUserName = xmldoc.SelectSingleNode("/xml/FromUserName");

            if (Event != null)
            {
                //菜单单击事件
                if (Event.InnerText.Equals("CLICK"))
                {
                    if (EventKey.InnerText.Equals("V1001_TODAY_MUSIC"))// 这个V1001_TODAY_MUSIC就是菜单里面的key
                    {
                        responseContent = string.Format(ReplyType.TextMessage,
                            FromUserName.InnerText,
                            ToUserName.InnerText,
                            DateTime.Now.Ticks,
                            "正在开发中,敬请期待!");
                    }
                    if (EventKey.InnerText.Equals("V1001_GOOD"))// 这个V1001_TODAY_MUSIC就是菜单里面的key
                    {
                        responseContent = string.Format(ReplyType.TextMessage,
                            FromUserName.InnerText,
                            ToUserName.InnerText,
                            DateTime.Now.Ticks,
                            "谢谢君的点赞,我们会更加努力的!");
                    }
                    if (EventKey.InnerText.Equals("V1001_TODAY_SINGER"))//获取文章  这个V1001_TODAY_SINGER就是菜单里面的key
                    {
                        responseContent = string.Format(ReplyType.Articles,
                            FromUserName.InnerText,
                            ToUserName.InnerText,
                            DateTime.Now.Ticks,2,
                            "", "", "http://cet.neea.edu.cn/query/images/160330152.png", ""
                            ,
                            "大学英语四六级成绩查询", "今天我们就来看看英语如何学习。。。。", "http://cet.neea.edu.cn/query/images/160330152.png", "http://cet.neea.edu.cn/cet");
                    }
                }
                else if (Event.InnerText.Equals("scancode_waitmsg")) //扫码推事件且弹出“消息接收中”提示框的事件推送 
                {
                    if (EventKey.InnerText.Equals("rselfmenu_0_0")) //点击防伪扫描
                    { //....处理返回逻辑
                        XmlNode ScanResult = xmldoc.SelectSingleNode("/xml/ScanCodeInfo/ScanResult");
                        responseContent = string.Format(ReplyType.TextMessage,
                            FromUserName.InnerText,
                            ToUserName.InnerText,
                            DateTime.Now.Ticks,
                            ScanResult.InnerText);
                    }
                }//关注时触发
                else if (Event.InnerText.Equals("subscribe"))
                {
                    responseContent = string.Format(ReplyType.TextMessage,
                            FromUserName.InnerText,
                            ToUserName.InnerText,
                            DateTime.Now.Ticks,
                            "谢谢君的关注,我们会更加努力的!");
                }//取消关注触发
                else if (Event.InnerText.Equals("unsubscribe"))
                {
                   
                }
                else if (Event.InnerText.Equals("SCAN"))
                {
                    responseContent = string.Format(ReplyType.TextMessage,
                            FromUserName.InnerText,
                            ToUserName.InnerText,
                            DateTime.Now.Ticks,
                            "谢谢君的关注,我们会更加努力的!");
                }
            }
            return responseContent;
        }

        //写入日志
        public static void WriteLog(string text)
        {
            StreamWriter sw = new StreamWriter(HttpContext.Current.Server.MapPath(".") + "\\log.txt", true);
            sw.WriteLine(text);
            sw.Close();
        }
    } 

三、通用的API类

 获取token、发送post请求、解析json、利用反射实现消息回复通用模板等方法类

using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Web;
using System.Xml;

/// <summary>
/// IWeixinAction 的摘要说明
/// </summary>
public class CommonApi
{
	public CommonApi()
	{
		//
		// TODO: 在此处添加构造函数逻辑
		//
	}
   /// <summary>
        /// 获取凭证接口
        /// </summary>
        /// <param name="grant_type">获取access_token填写client_credential</param>
        /// <param name="appid">第三方用户唯一凭证</param>
        /// <param name="secret">第三方用户唯一凭证密钥,既appsecret</param>
        /// <returns></returns>
        public static string GetAccessToken(string appid, string secret)
        {
            string token = OperationXml.GetXMLToken();
            if (token == "")
            {
                string strJson = RequestUrl(string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appid, secret));
                token = GetJsonValue(strJson, "access_token");
                OperationXml.UpdateXMLToken(token, DateTime.Now);
            }

            return token;
        }
 public static string RequestUrl(string strUrl)
        {
            // 设置参数
            HttpWebRequest request = WebRequest.Create(strUrl) as HttpWebRequest;
            CookieContainer cookieContainer = new CookieContainer();
            request.CookieContainer = cookieContainer;
            request.AllowAutoRedirect = true;
            request.Method = "POST";
            request.ContentType = "text/html";
            request.Headers.Add("charset", "utf-8");

            //发送请求并获取相应回应数据
            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
            //直到request.GetResponse()程序才开始向目标网页发送Post请求
            Stream responseStream = response.GetResponseStream();
            StreamReader sr = new StreamReader(responseStream, Encoding.UTF8);
            //返回结果网页(html)代码
            string content = sr.ReadToEnd();
            return content;
        }
 #region 解析用户列表json字符串,返回昵称为nickName的openid
 public string getValue(string json,string nickName) {
     JObject jobj = JObject.Parse(json);
     JToken jtoken = jobj["data"];
     for (int i = 0; i < jtoken["openid"].Children().Count(); i++)
     {
         //获取该用户的信息
         string result = GetResult("https://api.weixin.qq.com/cgi-bin/user/info?access_token=" + CommonApi.GetAccessToken("wxadf0f0c801b521fa", "35e3c8aeaa8c12d2bc76c1c12570bc96") + "&openid=" + jtoken["openid"][i].ToString());
         JObject resultObj = JObject.Parse(result);
         string nickname = resultObj["nickname"].ToString();
         if (nickname.Equals(nickName))
             return jtoken["openid"][i].ToString();
     }
     return null;
 }
 #endregion
 #region 获取响应url的json字符串
 public string GetResult(string posturl)
 {
     Stream instream = null;
     StreamReader sr = null;
     HttpWebResponse response = null;
     HttpWebRequest request = null;
     Encoding encoding = Encoding.UTF8;
     // 准备请求...
     try
     {
         // 设置参数
         request = WebRequest.Create(posturl) as HttpWebRequest;
         CookieContainer cookieContainer = new CookieContainer();
         request.CookieContainer = cookieContainer;
         request.AllowAutoRedirect = true;
         request.Method = "POST";
         request.ContentType = "application/x-www-form-urlencoded";
         //发送请求并获取相应回应数据
         response = request.GetResponse() as HttpWebResponse;
         //直到request.GetResponse()程序才开始向目标网页发送Post请求
         instream = response.GetResponseStream();
         sr = new StreamReader(instream, encoding);
         //返回结果网页(html)代码
         string content = sr.ReadToEnd();
         return content;
     }
     catch (Exception ex)
     {
         string err = ex.Message;
         return string.Empty;
     }
 }
 #endregion
 #region 获取Json字符串某节点的值

 /// <summary>
        /// 获取Json字符串某节点的值
        /// </summary>
        public static string GetJsonValue(string jsonStr, string key)
        {
            string result = string.Empty;
            if (!string.IsNullOrEmpty(jsonStr))
            {
                key = "\"" + key.Trim('"') + "\"";
                int index = jsonStr.IndexOf(key) + key.Length + 1;
                if (index > key.Length + 1)
                {
                    //先截逗号,若是最后一个,截“}”号,取最小值
                    int end = jsonStr.IndexOf(',', index);
                    if (end == -1)
                    {
                        end = jsonStr.IndexOf('}', index);
                    }

                    result = jsonStr.Substring(index, end - index);
                    result = result.Trim(new char[] { '"', ' ', '\''}); //过滤引号或空格
                }
            }
            return result;
        }

        #endregion
    #region 回复消息的xml模板
        public static string ReplayMesg<T>(XmlDocument xmldoc)
        {
            Dictionary<string,string> dictionary=new Dictionary<string,string>();
            //反射获取字段信息
            T t = default(T);
            t=Activator.CreateInstance<T>();
           FieldInfo[] infos= t.GetType().GetFields();
           foreach (FieldInfo info in infos)
           {
                dictionary.Add(info.Name,xmldoc.SelectSingleNode("/xml/"+info.Name).InnerText);
            }
            //获取信息xml模板
          string messageFormat= typeof(ReplyType).GetProperty(t.GetType().Name).GetValue(null).ToString();
       switch (dictionary["MsgType"])
       {
           case "text": return getFormat(dictionary, messageFormat, new object[] { dictionary["Content"]});
           case "image": return getFormat(dictionary, messageFormat, new object[] {dictionary["MediaId"] });
           case "voice": return getFormat(dictionary, messageFormat, new object[] { dictionary["MediaId"] });
           case "video": return getFormat(dictionary, messageFormat, new object[] { dictionary["MediaId"], "title", "description" });
       }
       return null;
        }
        private static string getFormat(Dictionary<string, string> dictionary, string messageFormat,params object []arr)
        {
            string responseContent = string.Empty;
            object[] arrs = new object[arr.Length+3];
            arrs[0]=dictionary["FromUserName"];
            arrs[1]= dictionary["ToUserName"];
            arrs[2] = DateTime.Now.Ticks;
            arr.CopyTo(arrs,3);
         return   responseContent = string.Format(messageFormat,arrs);
        }
     
    #endregion 
}

四、存储Token及创建时间在xml中

   每次Token的获取有效期为7200s,所以在获取是需要判断是否失效或者存在,如果为否则就获取新的Token并存储在xml中

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Xml;

/// <summary>
/// OperationXml 的摘要说明
/// </summary>
public class OperationXml
{
	public OperationXml()
	{
		//
		// TODO: 在此处添加构造函数逻辑
		//
	}
    /// <summary>
    /// 获取XML文件路径
    /// </summary>
    public static string xmlName = AppDomain.CurrentDomain.BaseDirectory + @"AccessToken.xml";

    /// <summary>
    /// 读取XML  Token
    /// </summary>
    /// <param name="xmlUrl"></param>
    /// <returns></returns>
    public static string GetXMLToken()
    {
        try
        {
            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.Load(xmlName);

            XmlNode xn = xmlDoc.SelectSingleNode("ACCESS_TOKEN");
            XmlElement xe = (XmlElement)xn;//将子节点类型转换为XmlElement类型 
            string Token = "";
            string CreateTime = "";
            foreach (XmlNode xn1 in xe)//遍历 
            {
                XmlElement xe2 = (XmlElement)xn1;//转换类型 
                if (xe2.Name == "Token")//如果找到 
                {
                    Token = xe2.InnerText;//则修改
                }
                if (xe2.Name == "CreateTime")//如果找到 
                {
                    CreateTime = xe2.InnerText;//则修改
                }
            }

            int seconds = 0;

            if (CreateTime.Trim() != "")
            {
                DateTime ct = Convert.ToDateTime(CreateTime);
                TimeSpan ts = (DateTime.Now - ct);
                seconds =ts.Days*24*60*60+ts.Hours*60*60+ts.Seconds+Convert.ToInt32(ts.Milliseconds*0.001);
            }
            MessageHelper.WriteLog("Token:" + Token);
            if (seconds > 7200 || seconds == 0)
            {
                return "";
            }
            else
            {
                return Token;
            }
        }
        catch (Exception ex)
        {
            MessageHelper.WriteLog("异常:" + ex.ToString());
            return "";
        }
    }

    /// <summary>
    /// 修改Token
    /// </summary>
    /// <param name="token"></param>
    /// <param name="createTime"></param>
    public static void UpdateXMLToken(string token, DateTime createTime)
    {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(xmlName);

        XmlNode xn = xmlDoc.SelectSingleNode("ACCESS_TOKEN");
        XmlElement xe = (XmlElement)xn;//将子节点类型转换为XmlElement类型 

        foreach (XmlNode xn1 in xe)//遍历 
        {
            XmlElement xe2 = (XmlElement)xn1;//转换类型 
            if (xe2.Name == "Token")//如果找到 
            {
                xe2.InnerText = token;//则修改
            }
            if (xe2.Name == "CreateTime")//如果找到 
            {
                xe2.InnerText = createTime.ToString();//则修改
            }
        }
        xmlDoc.Save(xmlName);

    }
}

五、消息回复xml模板

 这类中有一些没有用到的,就没有对他进行更改,我先应该可以能够看出来,用的话就需要自己去改了哦。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;

/// <summary>
/// ReplyType 的摘要说明
///     //回复类型
/// </summary>
public class ReplyType
{
	public ReplyType()
	{
		//
		// TODO: 在此处添加构造函数逻辑
		//
	}
        /// <summary>
        /// 普通文本消息
        /// </summary>
    public static string TextMessage
        {
            get
            {
                return @"<xml>
                            <ToUserName><![CDATA[{0}]]></ToUserName>
                            <FromUserName><![CDATA[{1}]]></FromUserName>
                            <CreateTime>{2}</CreateTime>
                            <MsgType><![CDATA[text]]></MsgType>
                            <Content><![CDATA[{3}]]></Content>
                            </xml>";
            }
        }
        /// <summary>
        /// 图片消息
        /// </summary>
        public static string Img
        {
            get
            {
                return @"<xml>
  <ToUserName><![CDATA[{0}]]></ToUserName>
  <FromUserName><![CDATA[{1}]]></FromUserName>
  <CreateTime>{2}</CreateTime>
  <MsgType><![CDATA[image]]></MsgType>
  <Image>
    <MediaId><![CDATA[{3}]]></MediaId>
  </Image>
</xml>";
            }
        }
        /// <summary>
        /// 图文消息
        /// </summary>
        public static string Articles
        {
            get
            {
                return @"<xml>
  <ToUserName><![CDATA[{0}]]></ToUserName>
  <FromUserName><![CDATA[{1}]]></FromUserName>
  <CreateTime>{2}</CreateTime>
  <MsgType><![CDATA[news]]></MsgType>
  <ArticleCount>{3}</ArticleCount>
  <Articles>
    <item>
      <Title><![CDATA[{4}]]></Title>
      <Description><![CDATA[{5}]]></Description>
      <PicUrl><![CDATA[{6}]]></PicUrl>
      <Url><![CDATA[{7}]]></Url>
    </item>
 <item>
      <Title><![CDATA[{8}]]></Title>
      <Description><![CDATA[{9}]]></Description>
      <PicUrl><![CDATA[{10}]]></PicUrl>
      <Url><![CDATA[{11}]]></Url>
    </item>
  </Articles>
</xml>";
            }
        }
        /// <summary>
        /// 语言消息
        /// </summary>
        public static string Voice
        {
            get
            {
                return @"<xml>
  <ToUserName><![CDATA[{0}]]></ToUserName>
  <FromUserName><![CDATA[{1}]]></FromUserName>
  <CreateTime>{2}</CreateTime>
  <MsgType><![CDATA[voice]]></MsgType>
  <Voice>
    <MediaId><![CDATA[{3}]]></MediaId>
  </Voice>
</xml>";
            }
        }
        /// <summary>
        /// 视频消息
        /// </summary>
        public static string Video
        {
            get
            {
                return @"<xml>
  <ToUserName><![CDATA[{0}]]></ToUserName>
  <FromUserName><![CDATA[{1}]]></FromUserName>
  <CreateTime>{2}</CreateTime>
  <MsgType><![CDATA[video]]></MsgType>
  <Video>
    <MediaId><![CDATA[{3}]]></MediaId>
    <Title><![CDATA[{4}]]></Title>
    <Description><![CDATA[{5}]]></Description>
  </Video>
</xml>";
            }
        }
        /// <summary>
        /// 音乐消息
        /// </summary>
        public static string Music
        {
            get
            {
                return @"<xml>
  <ToUserName><![CDATA[toUser]]></ToUserName>
  <FromUserName><![CDATA[fromUser]]></FromUserName>
  <CreateTime>12345678</CreateTime>
  <MsgType><![CDATA[music]]></MsgType>
  <Music>
    <Title><![CDATA[TITLE]]></Title>
    <Description><![CDATA[DESCRIPTION]]></Description>
    <MusicUrl><![CDATA[MUSIC_Url]]></MusicUrl>
    <HQMusicUrl><![CDATA[HQ_MUSIC_Url]]></HQMusicUrl>
    <ThumbMediaId><![CDATA[media_id]]></ThumbMediaId>
  </Music>
</xml>";
            }
        }
        /// <summary>
        /// 位置信息
        /// </summary>
        public static string Location
        {
            get
            {
                return @"<xml>
        <ToUserName><![CDATA[toUser]]></ToUserName>
        <FromUserName><![CDATA[fromUser]]></FromUserName>
        <CreateTime>1351776360</CreateTime>
        <MsgType><![CDATA[location]]></MsgType>
        <Location_X>23.134521</Location_X>
        <Location_Y>113.358803</Location_Y>
        <Scale>20</Scale>
        <Label><![CDATA[位置信息]]></Label>
        <MsgId>1234567890123456</MsgId>
        </xml>";
            }
        }
        /// <summary>
        /// 公众平台官网链接
        /// </summary>
        public static string Link
        {
            get
            {
                return @"<xml>
        <ToUserName><![CDATA[toUser]]></ToUserName>
        <FromUserName><![CDATA[fromUser]]></FromUserName>
        <CreateTime>1351776360</CreateTime>
        <MsgType><![CDATA[link]]></MsgType>
        <Title><![CDATA[公众平台官网链接]]></Title>
        <Description><![CDATA[公众平台官网链接]]></Description>
        <Url><![CDATA[url]]></Url>
        <MsgId>1234567890123456</MsgId>
        </xml>";
            }
        }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值