public async Task WriteAsync(object o) { var s = XmlConvert.SerializeObject(o); _logger.LogDebug("Response Body({0}): {1}", s?.Length, s); HttpContext.Response.Clear(); HttpContext.Response.ContentType = "text/plain;charset=utf-8"; var timestamp = WeixinTimestampHelper.FromUtcTime(DateTime.UtcNow); var nonce = new Random().Next(123456789, 987654321); var encrypted = _encryptor.Encrypt(s, timestamp.ToString(), nonce.ToString()); _logger.LogDebug("Encrypted Response Body({0}): {1}", encrypted?.Length, encrypted); await HttpContext.Response.WriteAsync(encrypted); }
/// <summary> /// 根据XML信息填充实实体 /// </summary> /// <typeparam name="T">MessageBase为基类的类型,Response和Request都可以</typeparam> /// <param name="entity">实体</param> /// <param name="doc">XML</param> public static void FillEntityWithXml <T>(this T entity, XDocument doc) where T : /*MessageBase*/ class, new() { entity = entity ?? new T(); var root = doc.Root; var props = entity.GetType().GetProperties(); foreach (var prop in props) { var propName = prop.Name; if (root.Element(propName) != null) { if (prop.PropertyType == typeof(DateTime)) { prop.SetValue(entity, WeixinTimestampHelper.ToLocalTime(root.Element(propName).Value), null); } else if (prop.PropertyType == typeof(Boolean) && (propName == "FuncFlag")) { prop.SetValue(entity, root.Element(propName).Value == "1", null); } else if (prop.PropertyType == typeof(Int32)) { prop.SetValue(entity, int.Parse(root.Element(propName).Value), null); } else if (prop.PropertyType == typeof(Int64)) { prop.SetValue(entity, long.Parse(root.Element(propName).Value), null); } else if (prop.PropertyType == typeof(Decimal)) { prop.SetValue(entity, decimal.Parse(root.Element(propName).Value), null); } else if (prop.PropertyType == typeof(Double)) { prop.SetValue(entity, double.Parse(root.Element(propName).Value), null); } else if (prop.PropertyType == typeof(ReceivedMsgType)) { //已设为只读 //prop.SetValue(entity, MsgTypeHelper.GetRequestMsgType(root.Element(propName).Value), null); } else if (prop.PropertyType == typeof(ResponseMsgType)) { //已设为只读 //prop.SetValue(entity, MsgTypeHelper.GetResponseMsgType(root.Element(propName).Value), null); } else if (prop.PropertyType == typeof(ReceivedEventType)) { //已设为只读 //prop.SetValue(entity, EventHelper.GetEventType(root.Element(propName).Value), null); } else if (prop.PropertyType == typeof(List <Article>)) { //var genericArguments = prop.PropertyType.GetGenericArguments(); //if (genericArguments[0].Name == "Article")//ResponseMessageNews适用 { //文章下属节点item List <Article> articles = new List <Article>(); foreach (var item in root.Element(propName).Elements("item")) { var article = new Article(); FillEntityWithXml(article, new XDocument(item)); articles.Add(article); } prop.SetValue(entity, articles, null); } } else if (prop.PropertyType == typeof(Music)) { Music music = new Music(); FillEntityWithXml(music, new XDocument(root.Element(propName))); prop.SetValue(entity, music, null); } else if (prop.PropertyType == typeof(Image)) { Image image = new Image(); FillEntityWithXml(image, new XDocument(root.Element(propName))); prop.SetValue(entity, image, null); } else if (prop.PropertyType == typeof(Voice)) { Voice voice = new Voice(); FillEntityWithXml(voice, new XDocument(root.Element(propName))); prop.SetValue(entity, voice, null); } else if (prop.PropertyType == typeof(Video)) { Video video = new Video(); FillEntityWithXml(video, new XDocument(root.Element(propName))); prop.SetValue(entity, video, null); } else { prop.SetValue(entity, root.Element(propName).Value, null); } } } }
/// <summary> /// 将实体转为XML /// </summary> /// <typeparam name="T">RequestMessage或ResponseMessage</typeparam> /// <param name="entity">实体</param> /// <returns></returns> public static XDocument ConvertEntityToXml <T>(this T entity) where T : class, new() { entity = entity ?? new T(); var doc = new XDocument(); doc.Add(new XElement("xml")); var root = doc.Root; /* 注意! * 经过测试,微信对字段排序有严格要求,这里对排序进行强制约束 */ var propNameOrder = new List <string>() { "ToUserName", "FromUserName", "CreateTime", "MsgType" }; //不同返回类型需要对应不同特殊格式的排序 if (entity is ResponseMessageNews) { propNameOrder.AddRange(new[] { "ArticleCount", "Articles", "FuncFlag", /*以下是Atricle属性*/ "Title ", "Description ", "PicUrl", "Url" }); } else if (entity is ResponseMessageMusic) { propNameOrder.AddRange(new[] { "Music", "FuncFlag", "ThumbMediaId", /*以下是Music属性*/ "Title ", "Description ", "MusicUrl", "HQMusicUrl" }); } else if (entity is ResponseMessageImage) { propNameOrder.AddRange(new[] { "Image", /*以下是Image属性*/ "MediaId " }); } else if (entity is ResponseMessageVoice) { propNameOrder.AddRange(new[] { "Voice", /*以下是Voice属性*/ "MediaId " }); } else if (entity is ResponseMessageVideo) { propNameOrder.AddRange(new[] { "Video", /*以下是Video属性*/ "MediaId ", "Title", "Description" }); } else { //如Text类型 propNameOrder.AddRange(new[] { "Content", "FuncFlag" }); } Func <string, int> orderByPropName = propNameOrder.IndexOf; var props = entity.GetType().GetProperties().OrderBy(p => orderByPropName(p.Name)).ToList(); foreach (var prop in props) { var propName = prop.Name; if (propName == "Articles") { //文章列表 var atriclesElement = new XElement("Articles"); var articales = prop.GetValue(entity, null) as List <Article>; foreach (var articale in articales) { var subNodes = ConvertEntityToXml(articale).Root.Elements(); atriclesElement.Add(new XElement("item", subNodes)); } root.Add(atriclesElement); } else if (propName == "Music" || propName == "Image" || propName == "Video" || propName == "Voice") { //音乐、图片、视频、语音格式 var musicElement = new XElement(propName); var media = prop.GetValue(entity, null);// as Music; var subNodes = ConvertEntityToXml(media).Root.Elements(); musicElement.Add(subNodes); root.Add(musicElement); } else { switch (prop.PropertyType.Name) { case "String": root.Add(new XElement(propName, new XCData(prop.GetValue(entity, null) as string ?? ""))); break; case "DateTime": root.Add(new XElement(propName, WeixinTimestampHelper.FromBeijingTime((DateTime)prop.GetValue(entity, null)))); break; case "Boolean": if (propName == "FuncFlag") { root.Add(new XElement(propName, (bool)prop.GetValue(entity, null) ? "1" : "0")); } else { goto default; } break; case "ResponseMsgType": root.Add(new XElement(propName, new XCData(prop.GetValue(entity, null).ToString().ToLower()))); break; case "Article": root.Add(new XElement(propName, prop.GetValue(entity, null).ToString().ToLower())); break; default: root.Add(new XElement(propName, prop.GetValue(entity, null))); break; } } } return(doc); }