.NET WeChat 開発パブリック アカウント メッセージ処理のコード例

Y2J
リリース: 2017-04-25 11:25:15
オリジナル
1764 人が閲覧しました

1. はじめに

WeChat パブリック プラットフォームのメッセージ処理は、最も基本的なテキスト メッセージ、画像メッセージ、音声メッセージ、ビデオ メッセージ、音楽メッセージがあります。送信された XML データが異なるだけです。メッセージを処理する前に、提供された公式ドキュメント mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html を注意深く読む必要があります。まず、最も基本的なテキスト メッセージの処理から始めます。


<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
ログイン後にコピー

これは、送信者、受信者、作成時間、タイプ、コンテンツなどを含む、メッセージ処理の最も基本的なパターンであることがわかります。

まず、メッセージ処理クラスを作成します。このクラスは、すべてのメッセージ要求をキャプチャし、さまざまなメッセージ要求タイプに応じてさまざまなメッセージ応答を処理するために使用されます。


public class WeiXinService
  {
    /// <summary>
    /// TOKEN
    /// </summary>
    private const string TOKEN = "finder";
    /// <summary>
    /// 签名
    /// </summary>
    private const string SIGNATURE = "signature";
    /// <summary>
    /// 时间戳
    /// </summary>
    private const string TIMESTAMP = "timestamp";
    /// <summary>
    /// 随机数
    /// </summary>
    private const string NONCE = "nonce";
    /// <summary>
    /// 随机字符串
    /// </summary>
    private const string ECHOSTR = "echostr";
    /// <summary>
    /// 
    /// </summary>
    private HttpRequest Request { get; set; }
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="request"></param>
    public WeiXinService(HttpRequest request)
    {
      this.Request = request;
    }
    /// <summary>
    /// 处理请求,产生响应
    /// </summary>
    /// <returns></returns>
    public string Response()
    {
      string method = Request.HttpMethod.ToUpper();
      //验证签名
      if (method == "GET")
      {
        if (CheckSignature())
        {
          return Request.QueryString[ECHOSTR];
        }
        else
        {
          return "error";
        }
      }
      //处理消息
      if (method == "POST")
      {
        return ResponseMsg();
      }
      else
      {
        return "无法处理";
      }
    }
    /// <summary>
    /// 处理请求
    /// </summary>
    /// <returns></returns>
    private string ResponseMsg()
    {
      string requestXml = CommonWeiXin.ReadRequest(this.Request);
      IHandler handler = HandlerFactory.CreateHandler(requestXml);
   
      if (handler != null)
      {
        return handler.HandleRequest();
      }

      return string.Empty;
    }
    /// <summary>
    /// 检查签名
    /// </summary>
    /// <param name="request"></param>
    /// <returns></returns>
    private bool CheckSignature()
    {
      string signature = Request.QueryString[SIGNATURE];
      string timestamp = Request.QueryString[TIMESTAMP];
      string nonce = Request.QueryString[NONCE];

      List<string> list = new List<string>();
      list.Add(TOKEN);
      list.Add(timestamp);
      list.Add(nonce);
      //排序
      list.Sort();
      //拼串
      string input = string.Empty;
      foreach (var item in list)
      {
        input += item;
      }
      //加密
      string new_signature = SecurityUtility.SHA1Encrypt(input);
      //验证
      if (new_signature == signature)
      {
        return true;
      }
      else
      {
        return false;
      }
    }
  }
ログイン後にコピー

そもそもメッセージをどのように捉えるか見てみましょう。ホームページの Default.ashx のコードは次のとおりです

    public void ProcessRequest(HttpContext context)
    {
      context.Response.ContentType = "text/html";
      

      string postString = string.Empty;
      if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
      {
        //由微信服务接收请求,具体处理请求
        WeiXinService wxService = new WeiXinService(context.Request);
        string responseMsg = wxService.Response();
        context.Response.Clear();
        context.Response.Charset = "UTF-8";
        context.Response.Write(responseMsg);
        context.Response.End();
      }
      else
      {
        string token = "wei2414201";
        if (string.IsNullOrEmpty(token))
        {
          return;
        }

        string echoString = HttpContext.Current.Request.QueryString["echoStr"];
        string signature = HttpContext.Current.Request.QueryString["signature"];
        string timestamp = HttpContext.Current.Request.QueryString["timestamp"];
        string nonce = HttpContext.Current.Request.QueryString["nonce"];

        if (!string.IsNullOrEmpty(echoString))
        {
          HttpContext.Current.Response.Write(echoString);
          HttpContext.Current.Response.End();
        }
      }


    }
ログイン後にコピー

上記のコードから、WeiXinService.cs クラスのメッセージが非常に重要であることがわかります。

    /// <summary>
    /// 处理请求
    /// </summary>
    /// <returns></returns>
    private string ResponseMsg()
    {
      string requestXml = CommonWeiXin.ReadRequest(this.Request);
      IHandler handler = HandlerFactory.CreateHandler(requestXml);
   
      if (handler != null)
      {
        return handler.HandleRequest();
      }

      return string.Empty;
    }
ログイン後にコピー

IHandler はメッセージ処理インターフェイスであり、その下に EventHandler があり、TextHandler 処理クラスはこのインターフェイスを実装します。コードは次のとおりです。

  /// <summary>
  /// 处理接口
  /// </summary>
  public interface IHandler
  {
    /// <summary>
    /// 处理请求
    /// </summary>
    /// <returns></returns>
    string HandleRequest();
  }
ログイン後にコピー

EventHandler

class EventHandler : IHandler
  {
    /// <summary>
    /// 请求的xml
    /// </summary>
    private string RequestXml { get; set; }
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="requestXml"></param>
    public EventHandler(string requestXml)
    {
      this.RequestXml = requestXml;
    }
    /// <summary>
    /// 处理请求
    /// </summary>
    /// <returns></returns>
    public string HandleRequest()
    {
      string response = string.Empty;
      EventMessage em = EventMessage.LoadFromXml(RequestXml);
      if (em.Event.Equals("subscribe", StringComparison.OrdinalIgnoreCase))//用来判断是不是首次关注
      {


        PicTextMessage tm = new PicTextMessage();//我自己创建的一个图文消息处理类
        tm.ToUserName = em.FromUserName;
        tm.FromUserName = em.ToUserName;
        tm.CreateTime = CommonWeiXin.GetNowTime();
        response = tm.GenerateContent();

      }

      return response;
    }
  }
ログイン後にコピー

TextHandler

  /// <summary>
  /// 文本信息处理类
  /// </summary>
  public class TextHandler : IHandler
  {
    string openid { get; set; }
    string access_token { get; set; }

    /// <summary>
    /// 请求的XML
    /// </summary>
    private string RequestXml { get; set; }
    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="requestXml">请求的xml</param>
    public TextHandler(string requestXml)
    {
      this.RequestXml = requestXml;
    }
    /// <summary>
    /// 处理请求
    /// </summary>
    /// <returns></returns>
    public string HandleRequest()
    {
      string response = string.Empty;
      TextMessage tm = TextMessage.LoadFromXml(RequestXml);
      string content = tm.Content.Trim();
      if (string.IsNullOrEmpty(content))
      {
        response = "您什么都没输入,没法帮您啊。";
      }
      else
      {
          string username = System.Configuration.ConfigurationManager.AppSettings["weixinid"].ToString();
          AccessToken token = AccessToken.Get(username);
          access_token = token.access_token;
          openid = tm.FromUserName;
          response = HandleOther(content);
        
      }
      tm.Content = response;
      //进行发送者、接收者转换
      string temp = tm.ToUserName;
      tm.ToUserName = tm.FromUserName;
      tm.FromUserName = temp;
      response = tm.GenerateContent();
      return response;
    }
    /// <summary>
    /// 处理其他消息
    /// </summary>
    /// <param name="tm"></param>
    /// <returns></returns>
    private string HandleOther(string requestContent)
    {
      string response = string.Empty;
      if (requestContent.Contains("你好") || requestContent.Contains("您好"))
      {
        response = "您也好~";
      }else if (requestContent.Contains("openid") || requestContent.Contains("id") || requestContent.Contains("ID"))//用来匹配用户输入的关键字
      {
        response = "你的Openid: "+openid;
      }
      else if (requestContent.Contains("token") || requestContent.Contains("access_token"))
      {
        response = "你的access_token: " + access_token;
      }else 
      {
        response = "试试其他关键字吧。";
      }
      return response;
    }
  }
ログイン後にコピー

HandlerFactory

  /// <summary>
  /// 处理器工厂类
  /// </summary>
  public class HandlerFactory
  {
    /// <summary>
    /// 创建处理器
    /// </summary>
    /// <param name="requestXml">请求的xml</param>
    /// <returns>IHandler对象</returns>
    public static IHandler CreateHandler(string requestXml)
    {
      IHandler handler = null;
      if (!string.IsNullOrEmpty(requestXml))
      {
        //解析数据
        XmlDocument doc = new System.Xml.XmlDocument();
        doc.LoadXml(requestXml);
        XmlNode node = doc.SelectSingleNode("/xml/MsgType");
        if (node != null)
        {
          XmlCDataSection section = node.FirstChild as XmlCDataSection;
          if (section != null)
          {
            string msgType = section.Value;

            switch (msgType)
            {
              case "text":
                handler = new TextHandler(requestXml);
                break;
              case "event":
                handler = new EventHandler(requestXml);
                break;
            }
          }
        }
      }

      return handler;
    }
  }
ログイン後にコピー

WeChat公式アカウントをフォローして、グラフィックメッセージを送信し、いくつかのキーワードを入力して完了しましょう。 ID を入力してユーザーの openid を返すなど、いくつかのメッセージを返します。

2.PicTextMessage

public class PicTextMessage : Message
  {
    /// <summary>
    /// 模板静态字段
    /// </summary>
    private static string m_Template;

    /// <summary>
    /// 默认构造函数
    /// </summary>
    public PicTextMessage()
    {
      this.MsgType = "news";
    }
    /// <summary>
    /// 从xml数据加载文本消息
    /// </summary>
    /// <param name="xml"></param>
    public static PicTextMessage LoadFromXml(string xml)
    {
      PicTextMessage tm = null;
      if (!string.IsNullOrEmpty(xml))
      {
        XElement element = XElement.Parse(xml);
        if (element != null)
        {
          tm = new PicTextMessage();
          tm.FromUserName = element.Element(CommonWeiXin.FROM_USERNAME).Value;
          tm.ToUserName = element.Element(CommonWeiXin.TO_USERNAME).Value;
          tm.CreateTime = element.Element(CommonWeiXin.CREATE_TIME).Value;
        }
      }

      return tm;
    }
    /// <summary>
    /// 模板
    /// </summary>
    public override string Template
    {
      get
      {
        if (string.IsNullOrEmpty(m_Template))
        {
          LoadTemplate();
        }

        return m_Template;
      }
    }
    /// <summary>
    /// 生成内容
    /// </summary>
    /// <returns></returns>
    public override string GenerateContent()
    {
      this.CreateTime = CommonWeiXin.GetNowTime();
      string str= string.Format(this.Template, this.ToUserName, this.FromUserName, this.CreateTime);
      return str;
    }


    /// <summary>
    /// 加载模板
    /// </summary>
    private static void LoadTemplate()
    {
      m_Template= @"<xml>
              <ToUserName><![CDATA[{0}]]></ToUserName>
              <FromUserName><![CDATA[{1}]]></FromUserName>
              <CreateTime>{2}</CreateTime>
              <MsgType><![CDATA[news]]></MsgType>
              <ArticleCount>1</ArticleCount>
              <Articles>
                <item>
                <Title><![CDATA[有位停车欢迎你!]]></Title> 
                <Description><![CDATA[如有问题请致电400-6238-136或直接在微信留言,我们将第一时间为您服务!]]></Description>
                <PicUrl><![CDATA[http://www.baidu.com/youwei.jpg]]></PicUrl>
                <Url><![CDATA[http://www.baidu.com]]></Url>
                </item>
              </Articles>
            </xml> ";
    }
  }
ログイン後にコピー

最終的な効果は次のとおりです。

以上が.NET WeChat 開発パブリック アカウント メッセージ処理のコード例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート