匿名通过本文主要向大家介绍了微信开发等相关知识,希望对您有所帮助,也希望大家支持linkedu.com www.linkedu.com
被动响应消息(返回XML)
微信要求我们返回XML数据,且格式是规定好的,具体请看
微信公众平台开发者文档。
响应的实体类,我们之前已经写好了,因为要求是XML格式。
我们在此使用微软提供的System.Xml.Serialization.XmlSerializer来将我们的数据序列化为XML。
所以我们在类上边标记了XmlRoot特性,在枚举的字段上边标记了XmlEnum特性,NewsMsg中在文章列表上标记了XmlArray和XmlArrayItem特性。而后反序列化出来的便是微信要求的格式了。
序列化方法如下:
public string ResponseXML(object value, Type type){
StringWriter sw = new StringWriter();
XmlSerializerNamespaces ns = new XmlSerializerNamespaces();
ns.Add("", ""); //去除命名空间
XmlSerializer serializer = new XmlSerializer(type);
serializer.Serialize(sw, value, ns); return sw.ToString();
}注意:此处必须去除XML的命名空间,不然微信不识别
完整方法奉上:
public HttpResponseMessage Post(){ var requestContent = Request.Content.ReadAsStreamAsync().Result; //从正文参数中加载微信的请求参数
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(requestContent);
logger.DebugFormat("WX请求XML内容:{0}", xmlDoc.InnerText); string msgTypeStr = xmlDoc.SelectSingleNode("xml/MsgType").InnerText; string userName = xmlDoc.SelectSingleNode("xml/FromUserName").InnerText; string efhName = xmlDoc.SelectSingleNode("xml/ToUserName").InnerText; string responseContent;
MsgType msgType;
//获取消息类型,若未定义,则返回。
if (!Enum.TryParse(msgTypeStr, true, out msgType))
{
responseContent = MsgService.Instance.ResponseXML(new TextMsg
{
FromUserName = efhName,
MsgType = MsgType.Text,
Content = "俺还小,不知道你在说啥子(⊙_⊙)?",
CreateTime = UnixTimestamp.Now.ToNumeric(),
ToUserName = userName
}, typeof(TextMsg)); return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(responseContent, Encoding.UTF8, "application/xml"),
};
} if (msgType == MsgType.Event)
{ return ProcessEvent(xmlDoc, userName, efhName);
}
//图灵消息转换为微信响应消息,下一节奉上
string content = xmlDoc.SelectSingleNode("xml/Content").InnerText; var requestResult = TuLingService.Instance.GetMsgFromResponse(content, userName, efhName);
responseContent = MsgService.Instance.ResponseXML(requestResult.Data, requestResult.DataType); return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(responseContent, Encoding.UTF8, "application/xml"),
};
}private HttpResponseMessage ProcessEvent(XmlDocument xmlDoc, string userName, string efhName){ string eventValue = xmlDoc.SelectSingleNode("xml/Event").InnerText; var responseContent = MsgService.Instance.ResponseXML(new TextMsg
{
FromUserName = efhName,
MsgType = MsgType.Text,
Content = eventValue.ToLower().Equals("subscribe") ? "lei好哇~" : "大爷,奴家会想你的",//其实取消订阅是不会发送消息的
CreateTime = UnixTimestamp.Now.ToNumeric(),
ToUserName = userName
}, typeof(TextMsg)); return new HttpResponseMessage(HttpStatusCode.OK)
{
Content = new StringContent(responseContent, Encoding.UTF8, "application/xml"),
};
}至此,我们已经完成了微信被动回复消息的响应。
映射图灵消息及微信消息
上边我们已经实现了被动回复消息的功能,接下来我们需要将图灵机器人接口与我们的公众平台关联起来。
分析图灵机器人返回的参数,我们发现所有类型的内容都有code和text参数。又因为我们需要将图灵的消息与微信的响应消息直接对应起来,因此我们定义接口,提供转换方法
public class TuLingResult{ //消息类型(我们在序列化为XML的时候需要提供类型)
public Type DataType { get; set; } public object Data { get; set; }
}public interface IResponse{ TuLingResult ToTuLingResult(string fromUserName, string toUserName);
}创建文本类数据的实体作为图灵消息的基类(对应微信的文本消息)
public class TextResult : IResponse{ public int Code { get; set; } public string Text { get; set; } public virtual TuLingResult ToTuLingResult(string fromUserName, string toUserName) { return new TuLingResult
{
DataType = typeof(TextMsg),
Data = new TextMsg
{
FromUserName = fromUserName,
ToUserName = toUserName,
Content = Text,
CreateTime = UnixTimestamp.Now.ToNumeric(),
MsgType = MsgType.Text
}
};
}
}而后依次创建各种数据的实体类。
如:新闻(对应微信的图文消息)
public class NewsResult : TextResult{ public List<NewsInfo> List { get; set; } public override TuLingResult ToTuLingResult(string fromUserName, string toUserName) { if (List.Count > 10)
{
List = List.Take(10).ToList();
} return new TuLingResult
{
DataType = typeof(NewsMsg),
Data = new NewsMsg
{
FromUserName = fromUserName,
ToUserName = toUserName,
ArticleCount = List.Count,
Articles = List.Select(m => new MsgNewsInfo
{
Title = m.Article,
Description = m.Source,
Url = m.DetailUrl,
PicUrl = m.Icon
}).ToList(),
CreateTime = UnixTimestamp.Now.ToNumeric(),
MsgType=MsgType.News
}
};
}
}public class NewsInfo{ /// <summary>
/// 标题
/// </summary>
public string Article { get; set; } /// <summary>
/// 来源
/// </summary>
public string Source { get; set; } /// <summary>
/// 详情地址
/// </summary>
public string DetailUrl { get; set; } /// <summary>
/// 图标地址
/// </summary>
public string Icon { get; set; }
}同理创建图灵机器人提供的各类数据实体类
我们想要支持的数据实体都定义完毕后,我们便可以开始请求图灵接口,获取真实的消息了,在此我们使用HttpClient实现。
private const string TULING_API_URL = "http://www.tuling123.com/openapi/api";private const string TULING_API_KEY = "XXXXX";//图灵的APIKEYpublic TuLingResult GetMsgFromResponse(string keyword, string userFlag, string efhName){ string linkString = string.Format("{0}?key={1}&info={2}&userid={3}"
, TULING_API_URL, TULING_API_KEY, keyword, userFlag); string content = string.Empty; using (HttpClient client = new HttpClient())
{
HttpResponseMessage response = client.GetAsync(linkString).Result;
content = response.Content.ReadAsStringAsync().Result;
logger.DebugFormat("图灵机器人响应:{0}", content);
} return ConvertToMsg(content, userFlag, efhName);
}图灵返回了code标识消息的类型和错误信息,因此我们先将响应

