微信公众号开发笔记(C#)

这篇文章还不错,使用  .net , 对微信用户的想公众号发送的文字进行回复。比较简单,自己可以修改更复杂的回复。

微信公众号开发笔记(C#)

原文地址

需求分析

根据用户在微信上发送至价值中国公众号的消息,查询与该消息相关的内容返回给用户。
例如,用户发送【美国经济】后收到包含【美国经济】的内容,点击可查看全文。若没有查询到相关内容,则返回默认消息。
 

运行环境

.NET
 

准备工作

1.在微信公众平台申请开发者。
2.功能页面完成后上传至自己的网站并能正常访问该URL(以下统称:目标接口)
3.在微信公众平台开启开发模式。
 

开发流程

1.验证签名,微信服务器会发一个GET请求到目标接口,接收参数后开始验证。
2.首先接收微信服务器发送的请求,然后进行处理,请求为xml格式,携带公众号、发送方微信号、消息类型,消息内容等结点。
3.根据消息类型,从数据库读取相关预设内容返回,要求响应时间在5秒内,返回格式同样是xml格式。
 

备注

输出内容一定要使用UTF-8的编码方式,否则中文会产生乱码。
如果消息中需要换行,使用\r\n来换行。
支持html的a标签,但是如果是换行是紧邻关系的话可能无法识别换行。
 
 完整代码
using System;
using System.IO;
using System.Text;
using System.Web;
using System.Web.Security;
using System.Xml;
 
public class WeChat : IHttpHandler
{    
    public void ProcessRequest(HttpContext context)
    {
        weixin wx = new weixin();
        String postStr = String.Empty;
 
        if (HttpContext.Current.Request.HttpMethod.ToUpper() == "POST")
        {
            Stream s = HttpContext.Current.Request.InputStream;
            Byte[] b = new Byte[s.Length];
            s.Read(b, 0, (Int32)s.Length);
            postStr = Encoding.UTF8.GetString(b);
 
            if (!String.IsNullOrEmpty(postStr))
            {
                wx.Handle(postStr);
            }
        }
        else
        {
            wx.Auth();
        }
    }
 
    public bool IsReusable
    {
        get
        {
            return false;
        }
    }
}
 
public class weixin
{
    private String Token = "改写为自己的Token";
    private String DefaultResponseContent = "欢迎关注价值中国\r\n价值中国是中国领先的财经商业领域社会化媒体";
 
    public void Auth()
    {
        String echoStr = HttpContext.Current.Request.QueryString["echoStr"];
 
        if (CheckSignature())
        {
            if (!String.IsNullOrEmpty(echoStr))
            {
                HttpContext.Current.Response.Write(echoStr);
                HttpContext.Current.Response.End();
            }
        }
    }
 
    public void Handle(String postStr)
    {
        XmlDocument doc = new XmlDocument();
        doc.LoadXml(postStr);
 
        XmlElement rootElement = doc.DocumentElement;
        XmlNode MsgType = rootElement.SelectSingleNode("MsgType");
 
        RequestXML requestXML = new RequestXML();
        requestXML.ToUserName = rootElement.SelectSingleNode("ToUserName").InnerText;
        requestXML.FromUserName = rootElement.SelectSingleNode("FromUserName").InnerText;
        requestXML.CreateTime = rootElement.SelectSingleNode("CreateTime").InnerText;
        requestXML.MsgType = MsgType.InnerText;
 
        if (requestXML.MsgType == "text")
        {
            requestXML.Content = rootElement.SelectSingleNode("Content").InnerText;
        }
 
        else if (requestXML.MsgType == "location")
        {
            requestXML.Location_X = rootElement.SelectSingleNode("Location_X").InnerText;
            requestXML.Location_Y = rootElement.SelectSingleNode("Location_Y").InnerText;
            requestXML.Scale = rootElement.SelectSingleNode("Scale").InnerText;
            requestXML.MapInfo = rootElement.SelectSingleNode("Label").InnerText;
        }
 
        else if (requestXML.MsgType == "image")
        {
            requestXML.PicUrl = rootElement.SelectSingleNode("PicUrl").InnerText;
        }
 
        ResponseMsg(requestXML);
    }
 
    /// 验证微信签名
    private bool CheckSignature()
    {
        String signature = HttpContext.Current.Request.QueryString["signature"];
        String timestamp = HttpContext.Current.Request.QueryString["timestamp"];
        String nonce = HttpContext.Current.Request.QueryString["nonce"];
        String[] ArrTmp = { Token, timestamp, nonce };
 
        Array.Sort(ArrTmp);
        String tmpStr = String.Join("", ArrTmp);
 
        tmpStr = FormsAuthentication.HashPasswordForStoringInConfigFile(tmpStr, "SHA1");
        tmpStr = tmpStr.ToLower();
 
        if (tmpStr == signature)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
 
    /// <summary>
    /// 回复消息
    /// </summary>
    /// <param name="weixinXML"></param>
    private void ResponseMsg(RequestXML requestXML)
    {
        String responseContent = String.Empty;
        
        if (requestXML.MsgType == "text")
        {
            responseContent = FormatTextXML(requestXML.FromUserName, requestXML.ToUserName, "从数据库读取的内容");
        }
 
        HttpContext.Current.Response.ContentEncoding = Encoding.UTF8;
        HttpContext.Current.Response.Write(responseContent);
    }
 
    /// 返回格式化文本XML内容
    private String FormatTextXML(String fromUserName, String toUserName, String content)
    {
        return "<xml><ToUserName><![CDATA[" + fromUserName + "]]></ToUserName><FromUserName><![CDATA[" + toUserName + "]]></FromUserName><CreateTime>" + ConvertDateTimeInt(DateTime.Now) + "</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[" + content + "]]></Content><FuncFlag>1</FuncFlag></xml>";
    }
 
    private int ConvertDateTimeInt(System.DateTime time)
    {
        System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));
        return (int)(time - startTime).TotalSeconds;
    }
}
 
 
//微信请求类
public class RequestXML
{
    private String toUserName = String.Empty;
 
    /// <summary>
    /// 公众号
    /// </summary>
    public String ToUserName
    {
        get { return toUserName; }
        set { toUserName = value; }
    }
 
    private String fromUserName = "";
 
    /// <summary>
    /// 发送方微信号
    /// </summary>
    public String FromUserName
    {
        get { return fromUserName; }
        set { fromUserName = value; }
    }
 
    private String createTime = String.Empty;
 
    /// <summary>
    /// 创建时间
    /// </summary>
    public String CreateTime
    {
        get { return createTime; }
        set { createTime = value; }
    }
 
    private String msgType = String.Empty;
 
    /// <summary>
    /// 信息类型 地理位置:location,文本消息:text,消息类型:image
    /// </summary>
    public String MsgType
    {
        get { return msgType; }
        set { msgType = value; }
    }
 
    private String content = String.Empty;
 
    /// <summary>
    /// 信息内容
    /// </summary>
    public String Content
    {
        get { return content; }
        set { content = value; }
    }
 
    private String location_X = String.Empty;
 
    /// <summary>
    /// 地理位置纬度
    /// </summary>
    public String Location_X
    {
        get { return location_X; }
        set { location_X = value; }
    }
 
    private String location_Y = String.Empty;
 
    /// <summary>
    /// 地理位置经度
    /// </summary>
    public String Location_Y
    {
        get { return location_Y; }
        set { location_Y = value; }
    }
 
    private String scale = String.Empty;
 
    /// <summary>
    /// 地图缩放大小
    /// </summary>
    public String Scale
    {
        get { return scale; }
        set { scale = value; }
    }
 
    private String mapInfo = String.Empty;
 
    /// <summary>
    /// 地理位置信息
    /// </summary>
    public String MapInfo
    {
        get { return mapInfo; }
        set { mapInfo = value; }
    }
 
    private String picUrl = String.Empty;
 
    /// <summary>
    /// 图片链接
    /// </summary>
    public String PicUrl
    {
        get { return picUrl; }
        set { picUrl = value; }
    }
 }
 
 
台州人在杭州 IT交流群416194041

欢迎在杭州的台州老乡加入交流!

 
 
 
 
 
 
 
 
 

本文转自Work Hard Work Smart博客园博客,原文链接:http://www.cnblogs.com/linlf03/p/4885974.html,如需转载请自行联系原作者
C#版的微信公众号开发SDK Senparc.Weixin.MP几个关键类介绍如下: Entities/Request*.cs 用于接收微信平台自动发送到服务器的实体(发送过来的是XML),包括文本、位置、图片三类 Entities/Response*.cs 用于反馈给发送人的信息实体(最终会转成XML),包括文本、新闻(图文)两类 Helpers/EntityHelper.cs 用于实体和XML之间的转换(由于其中有许多需要特殊处理的字段和类型,这里不能简单用XML序列化) Helpers/MsgTypeHelper.cs 用于获取消息类型 CheckSignature.cs 验证请求合法性类 Enums.cs 各种枚举 RequestMessageFactory.cs 用于自动生成不同Request类型的实体,并作必要的数据填充 Senparc.Weixin.MP几个关键类及重要方法(按一般使用过程排序) 生成验证字符串:Senparc.Weixin.MP.CheckSignature.GetSignature(string timestamp, string nonce, string token = null),返回根据微信平台提供的数据,SHA1加密后的验证字符串(注意token必须跟公众平台的设置一直) 验证请求:Senparc.Weixin.MP.CheckSignature.Check(string signature, string timestamp, string nonce, string token = null),验证请求是否合法 获取请求实体:var requestMessage = Senparc.Weixin.MP.RequestMessageFactory.GetRequestEntity(XDocument doc); 根据不同请求的类型,自动生成可用于操作的实体(doc只需要用XDocument.Parse(xmlString)就能生成),requestMessage.MsgType就是请求枚举类型。 进行判断及各类操作。 根据需要,创建响应类型的实体,如:var responseMessage = ResponseMessageBase.CreateFromRequestMessage(requestMessage, ResponseMsgType.Text) as ResponseMessageText; 即可返回文本类型信息。 由于目前微信只接受XML的返回数据,所以在返回之前还需要做一次转换:XDocument responseDoc = Senparc.Weixin.MP.Helpers.EntityHelper.ConvertEntityToXml(responseMessage); var xmlString =responseDoc.ToString();
Entities/Request*.cs 用于接收微信平台自动发送到服务器的实体(发送过来的是XML),包括文本、位置、图片三类 Entities/Response*.cs 用于反馈给发送人的信息实体(最终会转成XML),包括文本、新闻(图文)两类 Helpers/EntityHelper.cs 用于实体和XML之间的转换(由于其中有许多需要特殊处理的字段和类型,这里不能简单用XML序列化) Helpers/MsgTypeHelper.cs 用于获取消息类型 CheckSignature.cs 验证请求合法性类 Enums.cs 各种枚举 RequestMessageFactory.cs 用于自动生成不同Request类型的实体,并作必要的数据填充 Senparc.Weixin.MP几个关键类及重要方法(按一般使用过程排序) 生成验证字符串:Senparc.Weixin.MP.CheckSignature.GetSignature(string timestamp, string nonce, string token = null),返回根据微信平台提供的数据,SHA1加密后的验证字符串(注意token必须跟公众平台的设置一直) 验证请求:Senparc.Weixin.MP.CheckSignature.Check(string signature, string timestamp, string nonce, string token = null),验证请求是否合法 获取请求实体:var requestMessage = Senparc.Weixin.MP.RequestMessageFactory.GetRequestEntity(XDocument doc); 根据不同请求的类型,自动生成可用于操作的实体(doc只需要用XDocument.Parse(xmlString)就能生成),requestMessage.MsgType就是请求枚举类型。 进行判断及各类操作。 根据需要,创建响应类型的实体,如:var responseMessage = ResponseMessageBase.CreateFromRequestMessage(requestMessage, ResponseMsgType.Text) as ResponseMessageText; 即可返回文本类型信息。 由于目前微信只接受XML的返回数据,所以在返回之前还需要做一次转换:XDocument responseDoc = Senparc.Weixin.MP.Helpers.EntityHelper.ConvertEntityToXml(responseMessage); var xmlString =responseDoc.ToString(); 至此整个微信公众账号的自动响应过程结束。 下面可以直接下载源代码及示例(示例是ASP.NET MVC 4,.NET 4.0,为了提高兼容性,Senparc.Weixin.MP源代码使用.NET 3.5): 压缩包中包含三个文件夹:Senparc.Weixin.MP、Senparc.Weixin.MP.BuildOutPut、Senparc.Weixin.MP.Sample,分别对应Senparc.Weixin.MP.dll源代码项目、Senparc.Weixin.MP.dll输出目录、Web示例,Web示例建议放到公网测试,让公众平台自动发送
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值