diff --git a/src/Senparc.Weixin.MP/Senparc.Weixin.MP/AdvancedAPIs/GroupMessage/GroupMessageApi.cs b/src/Senparc.Weixin.MP/Senparc.Weixin.MP/AdvancedAPIs/GroupMessage/GroupMessageApi.cs new file mode 100644 index 0000000000..ee94446a97 --- /dev/null +++ b/src/Senparc.Weixin.MP/Senparc.Weixin.MP/AdvancedAPIs/GroupMessage/GroupMessageApi.cs @@ -0,0 +1,941 @@ +/*---------------------------------------------------------------- + Copyright (C) 2016 Senparc + + 文件名:GroupMessageAPI.cs + 文件功能描述:高级群发接口 + + + 创建标识:Senparc - 20150211 + + 修改标识:Senparc - 20150303 + 修改描述:整理接口 + + 修改标识:Senparc - 20150312 + 修改描述:开放代理请求超时时间 + + 修改标识:Senparc - 20160718 + 修改描述:增加其接口的异步方法 +----------------------------------------------------------------*/ + +/* + API地址:http://mp.weixin.qq.com/wiki/15/5380a4e6f02f2ffdc7981a8ed7a40753.html +*/ + +using System; +using System.Threading.Tasks; +using Senparc.Weixin.Entities; +using Senparc.Weixin.MP.AdvancedAPIs.GroupMessage; +using Senparc.Weixin.MP.CommonAPIs; +using Senparc.Weixin.HttpUtility; + +namespace Senparc.Weixin.MP.AdvancedAPIs +{ + /// + /// 高级群发接口 + /// + public static class GroupMessageApi + { + + #region 同步请求 + + + + /// + /// 根据分组进行群发【订阅号与服务号认证后均可用】 + /// + /// 请注意: + /// 1、该接口暂时仅提供给已微信认证的服务号 + /// 2、虽然开发者使用高级群发接口的每日调用限制为100次,但是用户每月只能接收4条,请小心测试 + /// 3、无论在公众平台网站上,还是使用接口群发,用户每月只能接收4条群发消息,多于4条的群发将对该用户发送失败。 + /// 4、群发视频时需要先调用GetVideoMediaIdResult接口获取专用的MediaId然后进行群发 + /// + /// + /// + /// 群发到的分组的group_id,参加用户管理中用户分组接口,若is_to_all值为true,可不填写group_id + /// 群发媒体文件时传入mediaId,群发文本消息时传入content,群发卡券时传入cardId + /// + /// 用于设定是否向全部用户发送,值为true或false,选择true该消息群发给所有用户,选择false可根据group_id发送给指定群组的用户 + /// 代理请求超时时间(毫秒) + /// + public static SendResult SendGroupMessageByGroupId(string accessTokenOrAppId, string groupId, string value, GroupMessageType type, bool isToAll = false, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token={0}"; + + BaseGroupMessageDataByGroupId baseData = null; + switch (type) + { + case GroupMessageType.image: + baseData = new GroupMessageByGroupId_ImageData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + image = new GroupMessageByGroupId_MediaId() + { + media_id = value + }, + msgtype = "image" + }; + break; + case GroupMessageType.voice: + baseData = new GroupMessageByGroupId_VoiceData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + voice = new GroupMessageByGroupId_MediaId() + { + media_id = value + }, + msgtype = "voice" + }; + break; + case GroupMessageType.mpnews: + baseData = new GroupMessageByGroupId_MpNewsData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + mpnews = new GroupMessageByGroupId_MediaId() + { + media_id = value + }, + msgtype = "mpnews" + }; + break; + case GroupMessageType.video: + baseData = new GroupMessageByGroupId_MpVideoData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + mpvideo = new GroupMessageByGroupId_MediaId() + { + media_id = value + }, + msgtype = "mpvideo" + }; + break; + case GroupMessageType.wxcard: + baseData = new GroupMessageByGroupId_WxCardData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + wxcard = new GroupMessageByGroupId_WxCard() + { + card_id = value + }, + msgtype = "wxcard" + }; + break; + case GroupMessageType.text: + baseData = new GroupMessageByGroupId_TextData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + text = new GroupMessageByGroupId_Content() + { + content = value + }, + msgtype = "text" + }; + break; + default: + throw new Exception("参数错误。"); + break; + } + + return CommonJsonSend.Send(accessToken, urlFormat, baseData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 根据OpenId进行群发 + /// + /// + /// 群发媒体文件时传入mediaId,群发文本消息时传入content,群发卡券时传入cardId + /// + /// openId字符串数组 + /// 代理请求超时时间(毫秒) + /// + public static SendResult SendGroupMessageByOpenId(string accessTokenOrAppId, GroupMessageType type, string value, int timeOut = Config.TIME_OUT, params string[] openIds) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token={0}"; + + BaseGroupMessageDataByOpenId baseData = null; + switch (type) + { + case GroupMessageType.image: + baseData = new GroupMessageByOpenId_ImageData() + { + touser = openIds, + image = new GroupMessageByOpenId_MediaId() + { + media_id = value + }, + msgtype = "image" + }; + break; + case GroupMessageType.voice: + baseData = new GroupMessageByOpenId_VoiceData() + { + touser = openIds, + voice = new GroupMessageByOpenId_MediaId() + { + media_id = value + }, + msgtype = "voice" + }; + break; + case GroupMessageType.mpnews: + baseData = new GroupMessageByOpenId_MpNewsData() + { + touser = openIds, + mpnews = new GroupMessageByOpenId_MediaId() + { + media_id = value + }, + msgtype = "mpnews" + }; + break; + case GroupMessageType.wxcard: + baseData = new GroupMessageByOpenId_WxCardData() + { + touser = openIds, + wxcard = new GroupMessageByOpenId_WxCard() + { + card_id = value + }, + msgtype = "wxcard" + }; + break; + case GroupMessageType.video: + throw new Exception("发送视频信息请使用SendVideoGroupMessageByOpenId方法。"); + break; + case GroupMessageType.text: + baseData = new GroupMessageByOpenId_TextData() + { + touser = openIds, + text = new GroupMessageByOpenId_Content() + { + content = value + }, + msgtype = "text" + }; + break; + default: + throw new Exception("参数错误。"); + break; + } + return CommonJsonSend.Send(accessToken, urlFormat, baseData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 根据OpenID列表群发视频消息【订阅号不可用,服务号认证后可用】 + /// 注意:群发视频时需要先调用GetVideoMediaIdResult接口获取专用的MediaId然后进行群发 + /// + /// + /// + /// + /// openId字符串数组 + /// + /// 代理请求超时时间(毫秒) + /// + public static SendResult SendVideoGroupMessageByOpenId(string accessTokenOrAppId, string title, string description, string mediaId, int timeOut = Config.TIME_OUT, params string[] openIds) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token={0}"; + + BaseGroupMessageDataByOpenId baseData = new GroupMessageByOpenId_MpVideoData() + { + touser = openIds, + video = new GroupMessageByOpenId_Video() + { + title = title, + description = description, + media_id = mediaId + }, + msgtype = "mpvideo" + }; + + return CommonJsonSend.Send(accessToken, urlFormat, baseData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 删除群发消息 + /// + /// + /// 发送出去的消息ID + /// 代理请求超时时间(毫秒) + /// + public static WxJsonResult DeleteSendMessage(string accessTokenOrAppId, string msgId, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + //官方API地址为https://api.weixin.qq.com//cgi-bin/message/mass/delete?access_token={0},应该是多了一个/ + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token={0}"; + + var data = new + { + msg_id = msgId + }; + return CommonJsonSend.Send(accessToken, urlFormat, data, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 预览接口【订阅号与服务号认证后均可用】 + /// 注意:openId与wxName两者任选其一,同时传入以wxName优先 + /// + /// + /// 群发媒体消息时为media_id,群发文本信息为content + /// + /// 接收消息用户对应该公众号的openid + /// 接收消息用户的微信号 + /// 代理请求超时时间(毫秒) + /// + public static SendResult SendGroupMessagePreview(string accessTokenOrAppId, GroupMessageType type, string value, string openId, string wxName = null, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token={0}"; + + BaseGroupMessageDataPreview baseData = null; + switch (type) + { + case GroupMessageType.image: + baseData = new GroupMessagePreview_ImageData() + { + touser = openId, + towxname = wxName, + image = new GroupMessagePreview_MediaId() + { + media_id = value + }, + msgtype = "image" + }; + break; + case GroupMessageType.voice: + baseData = new GroupMessagePreview_VoiceData() + { + touser = openId, + towxname = wxName, + voice = new GroupMessagePreview_MediaId() + { + media_id = value + }, + msgtype = "voice" + }; + break; + case GroupMessageType.mpnews: + baseData = new GroupMessagePreview_MpNewsData() + { + touser = openId, + towxname = wxName, + mpnews = new GroupMessagePreview_MediaId() + { + media_id = value + }, + msgtype = "mpnews" + }; + break; + case GroupMessageType.video: + baseData = new GroupMessagePreview_MpVideoData() + { + touser = openId, + towxname = wxName, + mpvideo = new GroupMessagePreview_MediaId() + { + media_id = value + }, + msgtype = "mpvideo" + }; + break; + case GroupMessageType.text: + baseData = new GroupMessagePreview_TextData() + { + touser = openId, + towxname = wxName, + text = new GroupMessagePreview_Content() + { + content = value + }, + msgtype = "text" + }; + break; + case GroupMessageType.wxcard: + throw new Exception("发送卡券息请使用WxCardGroupMessagePreview方法。"); + break; + default: + throw new Exception("参数错误。"); + break; + } + return CommonJsonSend.Send(accessToken, urlFormat, baseData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 预览卡券接口 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static SendResult WxCardGroupMessagePreview(string accessTokenOrAppId, string cardId, string code, + string openId, string wxName, string timestamp, string signature, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token={0}"; + + BaseGroupMessageDataPreview baseData = new GroupMessagePreview_WxCardData() + { + touser = openId, + towxname = wxName, + wxcard = new GroupMessagePreview_WxCard() + { + card_id = cardId, + card_ext = string.Format("\"code\":\"{0}\",\"openid\":\"{1}\",\"timestamp\":\"{2}\",\"signature\":\"{3}\"", code, openId, timestamp, signature) + }, + msgtype = "wxcard" + }; + + return CommonJsonSend.Send(accessToken, urlFormat, baseData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 查询群发消息发送状态【订阅号与服务号认证后均可用】 + /// + /// + /// 群发消息后返回的消息id + /// 代理请求超时时间(毫秒) + /// + public static GetSendResult GetGroupMessageResult(string accessTokenOrAppId, string msgId, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/get?access_token={0}"; + + var data = new + { + msg_id = msgId + }; + + return CommonJsonSend.Send(accessToken, urlFormat, data, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 获取视频群发用的MediaId + /// + /// + /// + /// + /// + /// + /// + public static VideoMediaIdResult GetVideoMediaIdResult(string accessTokenOrAppId, string mediaId, string title, + string description, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + string url = string.Format("https://file.api.weixin.qq.com/cgi-bin/media/uploadvideo?access_token={0}", accessToken.AsUrlData()); + + var data = new + { + media_id = mediaId, + title = title, + description = description + }; + + return CommonJsonSend.Send(null, url, data, CommonJsonSendType.POST, timeOut, true); + + }, accessTokenOrAppId); + } + #endregion + + #region 异步请求 + + /// + /// 【异步方法】根据分组进行群发【订阅号与服务号认证后均可用】 + /// + /// 请注意: + /// 1、该接口暂时仅提供给已微信认证的服务号 + /// 2、虽然开发者使用高级群发接口的每日调用限制为100次,但是用户每月只能接收4条,请小心测试 + /// 3、无论在公众平台网站上,还是使用接口群发,用户每月只能接收4条群发消息,多于4条的群发将对该用户发送失败。 + /// 4、群发视频时需要先调用GetVideoMediaIdResult接口获取专用的MediaId然后进行群发 + /// + /// + /// + /// 群发到的分组的group_id,参加用户管理中用户分组接口,若is_to_all值为true,可不填写group_id + /// 群发媒体文件时传入mediaId,群发文本消息时传入content,群发卡券时传入cardId + /// + /// 用于设定是否向全部用户发送,值为true或false,选择true该消息群发给所有用户,选择false可根据group_id发送给指定群组的用户 + /// 代理请求超时时间(毫秒) + /// + public static async Task SendGroupMessageByGroupIdAsync(string accessTokenOrAppId, string groupId, string value, GroupMessageType type, bool isToAll = false, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall?access_token={0}"; + + BaseGroupMessageDataByGroupId baseData = null; + switch (type) + { + case GroupMessageType.image: + baseData = new GroupMessageByGroupId_ImageData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + image = new GroupMessageByGroupId_MediaId() + { + media_id = value + }, + msgtype = "image" + }; + break; + case GroupMessageType.voice: + baseData = new GroupMessageByGroupId_VoiceData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + voice = new GroupMessageByGroupId_MediaId() + { + media_id = value + }, + msgtype = "voice" + }; + break; + case GroupMessageType.mpnews: + baseData = new GroupMessageByGroupId_MpNewsData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + mpnews = new GroupMessageByGroupId_MediaId() + { + media_id = value + }, + msgtype = "mpnews" + }; + break; + case GroupMessageType.video: + baseData = new GroupMessageByGroupId_MpVideoData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + mpvideo = new GroupMessageByGroupId_MediaId() + { + media_id = value + }, + msgtype = "mpvideo" + }; + break; + case GroupMessageType.wxcard: + baseData = new GroupMessageByGroupId_WxCardData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + wxcard = new GroupMessageByGroupId_WxCard() + { + card_id = value + }, + msgtype = "wxcard" + }; + break; + case GroupMessageType.text: + baseData = new GroupMessageByGroupId_TextData() + { + filter = new GroupMessageByGroupId_GroupId() + { + group_id = groupId, + is_to_all = isToAll + }, + text = new GroupMessageByGroupId_Content() + { + content = value + }, + msgtype = "text" + }; + break; + default: + throw new Exception("参数错误。"); + break; + } + + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, baseData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】根据OpenId进行群发 + /// + /// + /// 群发媒体文件时传入mediaId,群发文本消息时传入content,群发卡券时传入cardId + /// + /// openId字符串数组 + /// 代理请求超时时间(毫秒) + /// + public static async Task SendGroupMessageByOpenIdAsync(string accessTokenOrAppId, GroupMessageType type, string value, int timeOut = Config.TIME_OUT, params string[] openIds) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token={0}"; + + BaseGroupMessageDataByOpenId baseData = null; + switch (type) + { + case GroupMessageType.image: + baseData = new GroupMessageByOpenId_ImageData() + { + touser = openIds, + image = new GroupMessageByOpenId_MediaId() + { + media_id = value + }, + msgtype = "image" + }; + break; + case GroupMessageType.voice: + baseData = new GroupMessageByOpenId_VoiceData() + { + touser = openIds, + voice = new GroupMessageByOpenId_MediaId() + { + media_id = value + }, + msgtype = "voice" + }; + break; + case GroupMessageType.mpnews: + baseData = new GroupMessageByOpenId_MpNewsData() + { + touser = openIds, + mpnews = new GroupMessageByOpenId_MediaId() + { + media_id = value + }, + msgtype = "mpnews" + }; + break; + case GroupMessageType.wxcard: + baseData = new GroupMessageByOpenId_WxCardData() + { + touser = openIds, + wxcard = new GroupMessageByOpenId_WxCard() + { + card_id = value + }, + msgtype = "wxcard" + }; + break; + case GroupMessageType.video: + throw new Exception("发送视频信息请使用SendVideoGroupMessageByOpenId方法。"); + break; + case GroupMessageType.text: + baseData = new GroupMessageByOpenId_TextData() + { + touser = openIds, + text = new GroupMessageByOpenId_Content() + { + content = value + }, + msgtype = "text" + }; + break; + default: + throw new Exception("参数错误。"); + break; + } + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, baseData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】根据OpenID列表群发视频消息【订阅号不可用,服务号认证后可用】 + /// 注意:群发视频时需要先调用GetVideoMediaIdResult接口获取专用的MediaId然后进行群发 + /// + /// + /// + /// + /// openId字符串数组 + /// + /// 代理请求超时时间(毫秒) + /// + public static async Task SendVideoGroupMessageByOpenIdAsync(string accessTokenOrAppId, string title, string description, string mediaId, int timeOut = Config.TIME_OUT, params string[] openIds) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token={0}"; + + BaseGroupMessageDataByOpenId baseData = new GroupMessageByOpenId_MpVideoData() + { + touser = openIds, + video = new GroupMessageByOpenId_Video() + { + title = title, + description = description, + media_id = mediaId + }, + msgtype = "mpvideo" + }; + + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, baseData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】删除群发消息 + /// + /// + /// 发送出去的消息ID + /// 代理请求超时时间(毫秒) + /// + public static async Task DeleteSendMessageAsync(string accessTokenOrAppId, string msgId, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + //官方API地址为https://api.weixin.qq.com//cgi-bin/message/mass/delete?access_token={0},应该是多了一个/ + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/delete?access_token={0}"; + + var data = new + { + msg_id = msgId + }; + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, data, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】预览接口【订阅号与服务号认证后均可用】 + /// 注意:openId与wxName两者任选其一,同时传入以wxName优先 + /// + /// + /// 群发媒体消息时为media_id,群发文本信息为content + /// + /// 接收消息用户对应该公众号的openid + /// 接收消息用户的微信号 + /// 代理请求超时时间(毫秒) + /// + public static async Task SendGroupMessagePreviewAsync(string accessTokenOrAppId, GroupMessageType type, string value, string openId, string wxName = null, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token={0}"; + + BaseGroupMessageDataPreview baseData = null; + switch (type) + { + case GroupMessageType.image: + baseData = new GroupMessagePreview_ImageData() + { + touser = openId, + towxname = wxName, + image = new GroupMessagePreview_MediaId() + { + media_id = value + }, + msgtype = "image" + }; + break; + case GroupMessageType.voice: + baseData = new GroupMessagePreview_VoiceData() + { + touser = openId, + towxname = wxName, + voice = new GroupMessagePreview_MediaId() + { + media_id = value + }, + msgtype = "voice" + }; + break; + case GroupMessageType.mpnews: + baseData = new GroupMessagePreview_MpNewsData() + { + touser = openId, + towxname = wxName, + mpnews = new GroupMessagePreview_MediaId() + { + media_id = value + }, + msgtype = "mpnews" + }; + break; + case GroupMessageType.video: + baseData = new GroupMessagePreview_MpVideoData() + { + touser = openId, + towxname = wxName, + mpvideo = new GroupMessagePreview_MediaId() + { + media_id = value + }, + msgtype = "mpvideo" + }; + break; + case GroupMessageType.text: + baseData = new GroupMessagePreview_TextData() + { + touser = openId, + towxname = wxName, + text = new GroupMessagePreview_Content() + { + content = value + }, + msgtype = "text" + }; + break; + case GroupMessageType.wxcard: + throw new Exception("发送卡券息请使用WxCardGroupMessagePreview方法。"); + break; + default: + throw new Exception("参数错误。"); + break; + } + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, baseData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】预览卡券接口 + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public static async Task WxCardGroupMessagePreviewAsync(string accessTokenOrAppId, string cardId, string code, + string openId, string wxName, string timestamp, string signature, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token={0}"; + + BaseGroupMessageDataPreview baseData = new GroupMessagePreview_WxCardData() + { + touser = openId, + towxname = wxName, + wxcard = new GroupMessagePreview_WxCard() + { + card_id = cardId, + card_ext = string.Format("\"code\":\"{0}\",\"openid\":\"{1}\",\"timestamp\":\"{2}\",\"signature\":\"{3}\"", code, openId, timestamp, signature) + }, + msgtype = "wxcard" + }; + + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, baseData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】查询群发消息发送状态【订阅号与服务号认证后均可用】 + /// + /// + /// 群发消息后返回的消息id + /// 代理请求超时时间(毫秒) + /// + public static async Task GetGroupMessageResultAsync(string accessTokenOrAppId, string msgId, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/mass/get?access_token={0}"; + + var data = new + { + msg_id = msgId + }; + + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, data, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】获取视频群发用的MediaId + /// + /// + /// + /// + /// + /// + /// + public static async Task GetVideoMediaIdResultAsync(string accessTokenOrAppId, string mediaId, string title, + string description, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + string url = string.Format("https://file.api.weixin.qq.com/cgi-bin/media/uploadvideo?access_token={0}", accessToken.AsUrlData()); + + var data = new + { + media_id = mediaId, + title = title, + description = description + }; + + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(null, url, data, CommonJsonSendType.POST, timeOut, true); + + }, accessTokenOrAppId); + } + #endregion + } +} \ No newline at end of file diff --git a/src/Senparc.Weixin.MP/Senparc.Weixin.MP/AdvancedAPIs/TemplateMessage/TemplateApi.cs b/src/Senparc.Weixin.MP/Senparc.Weixin.MP/AdvancedAPIs/TemplateMessage/TemplateApi.cs new file mode 100644 index 0000000000..08aaf3a284 --- /dev/null +++ b/src/Senparc.Weixin.MP/Senparc.Weixin.MP/AdvancedAPIs/TemplateMessage/TemplateApi.cs @@ -0,0 +1,304 @@ +/*---------------------------------------------------------------- + Copyright (C) 2016 Senparc + + 文件名:TemplateAPI.cs + 文件功能描述:模板消息接口 + + + 创建标识:Senparc - 20150211 + + 修改标识:Senparc - 20150303 + 修改描述:整理接口 + + 修改标识:Senparc - 20150312 + 修改描述:开放代理请求超时时间 + + 修改标识:Senparc - 20160719 + 修改描述:增加其接口的异步方法 + + 修改标识:Senparc - 20160808 + 修改描述:去掉SendTemplateMessage,SendTemplateMessageAsync中的topcolor参数 +----------------------------------------------------------------*/ + +/* + API:http://mp.weixin.qq.com/wiki/17/304c1885ea66dbedf7dc170d84999a9d.html + */ + +using System; +using System.Threading.Tasks; +using Senparc.Weixin.Entities; +using Senparc.Weixin.MP.AdvancedAPIs.TemplateMessage; +using Senparc.Weixin.MP.CommonAPIs; + +namespace Senparc.Weixin.MP.AdvancedAPIs +{ + /// + /// 模板消息接口 + /// + public static class TemplateApi + { + #region 同步请求 + + /// + /// 模板消息接口 + /// + /// + /// + /// + /// + /// + /// 代理请求超时时间(毫秒) + /// + public static SendTemplateMessageResult SendTemplateMessage(string accessTokenOrAppId, string openId, string templateId, string url, object data, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={0}"; + var msgData = new TempleteModel() + { + touser = openId, + template_id = templateId, + // topcolor = topcolor, + url = url, + data = data + }; + return CommonJsonSend.Send(accessToken, urlFormat, msgData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 设置所属行业 + /// + /// + /// 公众号模板消息所属行业编号 + /// 公众号模板消息所属行业编号 + /// + /// + + public static WxJsonResult SetIndustry(string accessTokenOrAppId, IndustryCode industry_id1, IndustryCode industry_id2, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token={0}"; + var msgData = new + { + industry_id1 = ((int)industry_id1).ToString(), + industry_id2 = ((int)industry_id2).ToString() + }; + return CommonJsonSend.Send(accessToken, urlFormat, msgData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 获取设置的行业信息 + /// + /// + /// + /// + + public static GetIndustryJsonResult GetIndustry(string accessTokenOrAppId, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/template/get_industry?access_token={0}"; + return CommonJsonSend.Send(accessToken, urlFormat, null, CommonJsonSendType.GET, timeOut: timeOut); + + }, accessTokenOrAppId); + } + /// + /// 获得模板ID + /// + /// + /// 模板库中模板的编号,有“TM**”和“OPENTMTM**”等形式 + /// + /// + public static AddtemplateJsonResult Addtemplate(string accessTokenOrAppId, string template_id_short, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token={0}"; + var msgData = new + { + template_id_short = template_id_short + + }; + return CommonJsonSend.Send(accessToken, urlFormat, msgData, CommonJsonSendType.POST, timeOut: timeOut); + + }, accessTokenOrAppId); + } + /// + /// 获取模板列表 + /// + /// + /// + /// + + public static GetPrivateTemplateJsonResult GetPrivateTemplate(string accessTokenOrAppId, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token={0}"; + return CommonJsonSend.Send(accessToken, urlFormat, null, CommonJsonSendType.GET, timeOut: timeOut); + + }, accessTokenOrAppId); + } + /// + /// 删除模板 + /// + /// + /// 公众帐号下模板消息ID + /// + /// + public static WxJsonResult DelPrivateTemplate(string accessTokenOrAppId, string template_id, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/template/del_private_template?access_token={0}"; + var msgData = new + { + template_id = template_id + }; + + return CommonJsonSend.Send(accessToken, urlFormat, msgData, CommonJsonSendType.POST, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + #endregion + + #region 异步请求 + /// + /// 【异步方法】模板消息接口 + /// + /// + /// + /// + /// + /// + /// 代理请求超时时间(毫秒) + /// + public static async Task SendTemplateMessageAsync(string accessTokenOrAppId, string openId, string templateId, string url, object data, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={0}"; + var msgData = new TempleteModel() + { + touser = openId, + template_id = templateId, + // topcolor = topcolor, + url = url, + data = data + }; + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, msgData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】设置所属行业 + /// + /// + /// 公众号模板消息所属行业编号 + /// 公众号模板消息所属行业编号 + /// + /// + + public static async Task SetIndustryAsync(string accessTokenOrAppId, IndustryCode industry_id1, IndustryCode industry_id2, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/template/api_set_industry?access_token={0}"; + var msgData = new + { + industry_id1 = ((int)industry_id1).ToString(), + industry_id2 = ((int)industry_id2).ToString() + }; + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, msgData, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】获取设置的行业信息 + /// + /// + /// + /// + + public static async Task GetIndustryAsync(string accessTokenOrAppId, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/template/get_industry?access_token={0}"; + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, null, CommonJsonSendType.GET, timeOut: timeOut); + + }, accessTokenOrAppId); + } + /// + /// 【异步方法】获得模板ID + /// + /// + /// 模板库中模板的编号,有“TM**”和“OPENTMTM**”等形式 + /// + /// + public static async Task AddtemplateAsync(string accessTokenOrAppId, string template_id_short, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token={0}"; + var msgData = new + { + template_id_short = template_id_short + + }; + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, msgData, CommonJsonSendType.POST, timeOut: timeOut); + + }, accessTokenOrAppId); + } + /// + ///【异步办法】 获取模板列表 + /// + /// + /// + /// + + public static async Task GetPrivateTemplateAsync(string accessTokenOrAppId, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token={0}"; + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, null, CommonJsonSendType.GET, timeOut: timeOut); + + }, accessTokenOrAppId); + } + /// + /// 【异步方法】删除模板 + /// + /// + /// 公众帐号下模板消息ID + /// + /// + public static async Task DelPrivateTemplateAsync(string accessTokenOrAppId, string template_id, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync(accessToken => + { + const string urlFormat = "https://api.weixin.qq.com/cgi-bin/template/del_private_template?access_token={0}"; + var msgData = new + { + template_id = template_id + }; + + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, urlFormat, msgData, CommonJsonSendType.POST, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + #endregion + + + + } +} \ No newline at end of file diff --git a/src/Senparc.Weixin.MP/Senparc.Weixin.MP/AdvancedAPIs/User/UserApi.cs b/src/Senparc.Weixin.MP/Senparc.Weixin.MP/AdvancedAPIs/User/UserApi.cs new file mode 100644 index 0000000000..340508b29a --- /dev/null +++ b/src/Senparc.Weixin.MP/Senparc.Weixin.MP/AdvancedAPIs/User/UserApi.cs @@ -0,0 +1,217 @@ +/*---------------------------------------------------------------- + Copyright (C) 2016 Senparc + + 文件名:UserAPI.cs + 文件功能描述:用户接口 + + + 创建标识:Senparc - 20150211 + + 修改标识:Senparc - 20150303 + 修改描述:整理接口 + + 修改标识:jsionr - 20150322 + 修改描述:添加修改关注者备注信息接口 + + 修改标识:Senparc - 20150325 + 修改描述:修改关注者备注信息开放代理请求超时时间 + + 修改标识:Senparc - 20160719 + 修改描述:增加其接口的异步方法 + +----------------------------------------------------------------*/ + +/* + 接口详见:http://mp.weixin.qq.com/wiki/index.php?title=%E8%8E%B7%E5%8F%96%E7%94%A8%E6%88%B7%E5%9F%BA%E6%9C%AC%E4%BF%A1%E6%81%AF + */ + +using System.Collections.Generic; +using System.Threading.Tasks; +using Senparc.Weixin.Entities; +using Senparc.Weixin.MP.AdvancedAPIs.User; +using Senparc.Weixin.MP.CommonAPIs; +using Senparc.Weixin.HttpUtility; + +namespace Senparc.Weixin.MP.AdvancedAPIs +{ + /// + /// 用户接口 + /// + public static class UserApi + { + #region 同步请求 + + /// + /// 获取用户信息 + /// + /// 调用接口凭证 + /// 普通用户的标识,对当前公众号唯一 + /// 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语 + /// + public static UserInfoJson Info(string accessTokenOrAppId, string openId, Language lang = Language.zh_CN) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang={2}", + accessToken.AsUrlData(), openId.AsUrlData(), lang.ToString("g").AsUrlData()); + return HttpUtility.Get.GetJson(url); + + //错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误): + //{"errcode":40013,"errmsg":"invalid appid"} + + }, accessTokenOrAppId); + } + + /// + /// 获取关注者OpenId信息 + /// + /// + /// + /// + public static OpenIdResultJson Get(string accessTokenOrAppId, string nextOpenId) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/get?access_token={0}", accessToken.AsUrlData()); + if (!string.IsNullOrEmpty(nextOpenId)) + { + url += "&next_openid=" + nextOpenId; + } + return HttpUtility.Get.GetJson(url); + + }, accessTokenOrAppId); + } + + /// + /// 修改关注者备注信息 + /// + /// 调用接口凭证 + /// 普通用户的标识,对当前公众号唯一 + /// 新的备注名,长度必须小于30字符 + /// 代理请求超时时间(毫秒) + /// + public static WxJsonResult UpdateRemark(string accessTokenOrAppId, string openId, string remark, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token={0}", accessToken.AsUrlData()); + var data = new + { + openid = openId, + remark = remark + }; + return CommonJsonSend.Send(accessToken, url, data, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 批量获取用户基本信息 + /// + /// + /// + /// + /// + public static BatchGetUserInfoJsonResult BatchGetUserInfo(string accessTokenOrAppId, List userList, int timeOut = Config.TIME_OUT) + { + return ApiHandlerWapper.TryCommonApi(accessToken => + { + string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token={0}", accessToken.AsUrlData()); + var data = new + { + user_list = userList, + }; + return CommonJsonSend.Send(accessToken, url, data, timeOut: timeOut); + + }, accessTokenOrAppId); + } + #endregion + + #region 异步请求 + /// + /// 【异步方法】获取用户信息 + /// + /// 调用接口凭证 + /// 普通用户的标识,对当前公众号唯一 + /// 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语 + /// + public static async Task InfoAsync(string accessTokenOrAppId, string openId, Language lang = Language.zh_CN) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info?access_token={0}&openid={1}&lang={2}", + accessToken.AsUrlData(), openId.AsUrlData(), lang.ToString("g").AsUrlData()); + return HttpUtility.Get.GetJsonAsync(url); + + //错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误): + //{"errcode":40013,"errmsg":"invalid appid"} + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】获取关注者OpenId信息 + /// + /// + /// + /// + public static async Task GetAsync(string accessTokenOrAppId, string nextOpenId) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/get?access_token={0}", accessToken.AsUrlData()); + if (!string.IsNullOrEmpty(nextOpenId)) + { + url += "&next_openid=" + nextOpenId; + } + return HttpUtility.Get.GetJsonAsync(url); + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】修改关注者备注信息 + /// + /// 调用接口凭证 + /// 普通用户的标识,对当前公众号唯一 + /// 新的备注名,长度必须小于30字符 + /// 代理请求超时时间(毫秒) + /// + public static async Task UpdateRemarkAsync(string accessTokenOrAppId, string openId, string remark, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info/updateremark?access_token={0}", accessToken.AsUrlData()); + var data = new + { + openid = openId, + remark = remark + }; + return Senparc.Weixin .CommonAPIs .CommonJsonSend.SendAsync(accessToken, url, data, timeOut: timeOut); + + }, accessTokenOrAppId); + } + + /// + /// 【异步方法】批量获取用户基本信息 + /// + /// + /// + /// + /// + public static async Task BatchGetUserInfoAsync(string accessTokenOrAppId, List userList, int timeOut = Config.TIME_OUT) + { + return await ApiHandlerWapper.TryCommonApiAsync( accessToken => + { + string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token={0}", accessToken.AsUrlData()); + var data = new + { + user_list = userList, + }; + return Senparc.Weixin.CommonAPIs.CommonJsonSend.SendAsync(accessToken, url, data, timeOut: timeOut); + + }, accessTokenOrAppId); + } + #endregion + } +} diff --git a/src/Senparc.Weixin.MP/Senparc.Weixin.MP/TenPayLib/TenPayHttpClient.cs b/src/Senparc.Weixin.MP/Senparc.Weixin.MP/TenPayLib/TenPayHttpClient.cs new file mode 100644 index 0000000000..3719b9d2c3 --- /dev/null +++ b/src/Senparc.Weixin.MP/Senparc.Weixin.MP/TenPayLib/TenPayHttpClient.cs @@ -0,0 +1,292 @@ +/*---------------------------------------------------------------- + Copyright (C) 2016 Senparc + + 文件名:TenPayHttpClient.cs + 文件功能描述:微信支付http、https通信类 + + + 创建标识:Senparc - 20150211 + + 修改标识:Senparc - 20150303 + 修改描述:整理接口 +----------------------------------------------------------------*/ + +using System; +using System.IO; +using System.Net; +using System.Net.Security; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Text.RegularExpressions; + +/** + * http、https通信类 + * ============================================================================ + * api说明: + * setReqContent($reqContent),设置请求内容,无论post和get,都用get方式提供 + * getResContent(), 获取应答内容 + * setMethod($method),设置请求方法,post或者get + * getErrInfo(),获取错误信息 + * setCertInfo($certFile, $certPasswd, $certType="PEM"),设置证书,双向https时需要使用 + * setCaInfo($caFile), 设置CA,格式未pem,不设置则不检查 + * setTimeOut($timeOut), 设置超时时间,单位秒 + * getResponseCode(), 取返回的http状态码 + * call(),真正调用接口 + * + * ============================================================================ + * + */ + +namespace Senparc.Weixin.MP.TenPayLib +{ + public class TenPayHttpClient + { + /// + /// 请求内容,无论post和get,都用get方式提供 + /// + private string ReqContent; + + /// + /// 应答内容 + /// + private string ResContent; + + /// + /// 请求方法 + /// + private string Method; + + /// + /// 错误信息 + /// + private string ErrInfo; + + /// + /// 证书文件 + /// + + private string CertFile; + + /// + /// 证书密码 + /// + private string CertPasswd; + + /// + /// ca证书文件 + /// + private string CaFile; + + /// + /// 超时时间,以秒为单位 + /// + private int TimeOut; + + /// + /// http应答编码 + /// + + private int ResponseCode; + + /// + /// 字符编码 + /// + private string Charset; + + public TenPayHttpClient() + { + this.CaFile = ""; + this.CertFile = ""; + this.CertPasswd = ""; + + this.ReqContent = ""; + this.ResContent = ""; + this.Method = "POST"; + this.ErrInfo = ""; + this.TimeOut = 1 * 60;//5分钟 + + this.ResponseCode = 0; + this.Charset = "gb2312"; + + } + + /// + /// 设置请求内容 + /// + /// + public void SetReqContent(string reqContent) + { + this.ReqContent = reqContent; + } + + /// + /// 获取结果内容 + /// + /// + public string GetResContent() + { + return this.ResContent; + } + + /// + /// 设置请求方法post或者get + /// + /// + + public void SetMethod(string method) + { + this.Method = method; + } + + /// + /// 获取错误信息 + /// + /// + public string GetErrInfo() + { + return this.ErrInfo; + } + + /// + /// 设置证书信息 + /// + /// + /// + public void SetCertInfo(string certFile, string certPasswd) + { + this.CertFile = certFile; + this.CertPasswd = certPasswd; + } + + /// + /// 设置ca + /// + /// + public void SetCaInfo(string caFile) + { + this.CaFile = caFile; + } + + /// + /// 设置超时时间,以秒为单位 + /// + /// + public void SetTimeOut(int timeOut) + { + this.TimeOut = timeOut; + } + + + /// + /// 获取http状态码 + /// + /// + public int GetResponseCode() + { + return this.ResponseCode; + } + + public void SetCharset(string charset) + { + this.Charset = charset; + } + + /// + /// 验证服务器证书 + /// + /// + /// + /// + /// + /// + public bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors) + { + return true; + } + + /// + /// 执行http调用 + /// + /// + public bool Call() + { + StreamReader sr = null; + HttpWebResponse wr = null; + + HttpWebRequest hp = null; + try + { + string postData = null; + if (this.Method.ToUpper() == "POST") + { + string[] sArray = Regex.Split(this.ReqContent, "\\?"); + + hp = (HttpWebRequest)WebRequest.Create(sArray[0]); + + if (sArray.Length >= 2) + { + postData = sArray[1]; + } + + } + else + { + hp = (HttpWebRequest)WebRequest.Create(this.ReqContent); + } + + + ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult); + if (this.CertFile != "") + { + hp.ClientCertificates.Add(new X509Certificate2(this.CertFile, this.CertPasswd)); + } + hp.Timeout = this.TimeOut * 1000; + + Encoding encoding = Encoding.GetEncoding(this.Charset); + if (postData != null) + { + byte[] data = encoding.GetBytes(postData); + + hp.Method = "POST"; + + hp.ContentType = "application/x-www-form-urlencoded"; + + hp.ContentLength = data.Length; + + Stream ws = hp.GetRequestStream(); + + // 发送数据 + + ws.Write(data, 0, data.Length); + ws.Close(); + + + } + + + wr = (HttpWebResponse)hp.GetResponse(); + sr = new StreamReader(wr.GetResponseStream(), encoding); + + + + this.ResContent = sr.ReadToEnd(); + sr.Close(); + wr.Close(); + } + catch (Exception exp) + { + this.ErrInfo += exp.Message; + if (wr != null) + { + this.ResponseCode = Convert.ToInt32(wr.StatusCode); + } + + return false; + } + + this.ResponseCode = Convert.ToInt32(wr.StatusCode); + + return true; + } + } +}