Skip to content

处理微信信息的常规方法

JeffreySu edited this page Apr 26, 2013 · 2 revisions

阅读说明:这里的“常规方法”展示了SDK处理消息的基本逻辑,但是由于微信消息类型众多、结构复杂等原因,这种处理方式在日常开发中会显得比较繁琐,为此我们封装了MessageHandler,以便更加简便地处理消息,实际开发过程中,我们推荐直接使用MessageHandler(并且MessageHandler已经封装了用户会话上下文模块)。详见:如何使用MessageHandler简化消息处理流程

###如何处理微信POST请求?

只需要在Action中使用RequestMessageFactory.GetRequestEntity(doc),就能得到微信发来的所有请求:

XDocument doc = XDocument.Load(Request.InputStream);
var requestMessage = RequestMessageFactory.GetRequestEntity(doc);

如果你不需要得到XML这个“原始数据”,那么只需一行:

var requestMessage = RequestMessageFactory.GetRequestEntity(Request.InputStream);

###如何响应不同类型的请求? 通过requestMessage.MsgType分析请求的类型,并作出不同回应,如:

switch (requestMessage.MsgType)
{
    case RequestMsgType.Text://文字类型
        {
            //TODO:交给Service处理具体信息,参考/Service/EventSercice.cs 及 /Service/LocationSercice.cs
            var strongRequestMessage = requestMessage as RequestMessageText;
            var strongresponseMessage =
                     ResponseMessageBase.CreateFromRequestMessage(requestMessage, ResponseMsgType.Text) as
                     ResponseMessageText;
            strongresponseMessage.Content =
                string.Format(
                    "您刚才发送了文字信息:{0}\r\n您还可以发送【位置】【图片】【语音】信息,查看不同格式的回复。\r\nSDK官方地址:http://weixin.senparc.com",
                    strongRequestMessage.Content);
            responseMessage = strongresponseMessage;
            break;
        }
    case RequestMsgType.Location://地理位置
        ...
        break;
    case RequestMsgType.Image://图片
        ...
        break;
        case RequestMsgType.Voice://语音
        ...
        break;
    default:
        throw new ArgumentOutOfRangeException();
}

上述代码中,当确定requestMessage.MsgType为RequestMsgType.Text时,可以大胆使用转换(由RequestMessageFactory负责自动完成):

var strongRequestMessage = requestMessage as RequestMessageText;

其他类型以此类推。

对于v0.3之后的版本,我们对ResponseMessageBase.CreateFromRequestMessage也有了更加漂亮的替代写法(原方法仍然是基础,可用):

var strongRequestMessage = ResponseMessageBase.CreateFromRequestMessage<ResponseMessageText>(RequestMessage);

其中ResponseMessageText就是期望返回的消息类型。

除了上述繁琐而且丑陋的switch判断方法外,Senparc.Weixin.MP提供了更加简便、干净的消息处理方法用于完全取代这里的switch和if(当然在此之前最好能对上面的代码原理有所了解),MessageHandler,详细介绍请看:如何使用MessageHandler简化消息处理流程

###如何生成要返回的数据? 当需要返回数据时,只需要这样做:

var strongresponseMessage = ResponseMessageBase.CreateFromRequestMessage(requestMessage, ResponseMsgType.Text) as ResponseMessageText;

ResponseMessageBase.CreateFromRequestMessage()方法负责生成对应ResponseMsgType类型的响应类型实例,其中经过了对换收/发方地址(OpenID)、定义创建时间等一系列自动操作。

其中,requestMessage是上一步中获取到的微信服务器请求数据,ResponseMsgType.Text是返回数据类型,可以是文字、新闻(图片)、语音、音乐等。 ResponseMessageText类型和ResponseMsgType.Text对应,其他类型以此类推(由ResponseMessageFactory负责自动完成)。

###如何把结果返回给微信服务器? 第一步:把ResponseMessage生成XML(由于微信的个别特殊机制,不能简单序列化):

var responseDoc = MP.Helpers.EntityHelper.ConvertEntityToXml(responseMessage);

第二步:在Action中直接返回responseDoc(XDocument类型)的XML字符串。

return Content(responseDoc.ToString());

如果你不需要responseDoc这个XML“中间数据”,那么以上两步只需要换做一行(加上using Senparc.Weixin.MP.Helpers):

return Content(responseMessage.ConvertEntityToXmlString());

至此整个响应过程结束。