模板消息发送帮助类:
public class ComSendWXMsg { /// <summary> /// 连接字符串 /// </summary> private static string wxconStr = StaticData.GetWXXXKDBStr(); /// <summary> /// 数据库帮助对象 /// </summary> private static SDJWSqlHelper wxHelper = new SDJWSqlHelper(wxconStr); #region 获取微信消息发送用的 数据库链接串 /// <summary> /// 获取微信发送消息数据库链接(解密后) /// </summary> /// <returns></returns> public static string GetDBConnectionStr(int YYID) { string returnStr = string.Empty; string strSQL = string.Empty; strSQL = @" SELECT DBLJ FROM WX_SendMsgsYYB T INNER JOIN WX_GZHXXB T1 ON T.GZHID = T1.id WHERE T.ZFPB = 0 AND T.ID = " + YYID.ToString(); DataSet ds = wxHelper.ExecSqlReDs(strSQL.ToString()); if (ds != null || ds.Tables[0] != null) { if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { returnStr = EnOrDecrypt.DecryptStr(ds.Tables[0].Rows[0][0].ToString()); } } return returnStr; } #endregion #region 查询消息发送对象辅助信息 /// <summary> /// 查询消息发送对象辅助信息 /// </summary> /// <param name="yyID">所属应用ID</param> /// <param name="dxMC">对象名称</param> /// <param name="classID">类别(1:自动 2:手动 3:定时)</param> /// <returns></returns> public static WXDataHelper GetWxDXData(int yyID, string dxMC, int classID) { WXDataHelper model = new WXDataHelper(); string strSQL = string.Empty; strSQL = @" SELECT T.ID, T.YYID, T.DXMC, T.TMPID, T.MBMXZH, T.XQURL, T1.MBID FROM WX_SendMsgsDX T LEFT JOIN WX_TemplateMsgsId T1 ON T.TMPID = T1.ID WHERE T.ZFPB = 0 AND T.YYID = @YYID AND T.DXMC = @DXMC AND T.CLASSID = @CLASSID"; SqlParameter[] paras = new SqlParameter[] { new SqlParameter("@YYID",SqlDbType.Int), new SqlParameter("@DXMC",SqlDbType.NVarChar,50), new SqlParameter("@CLASSID",SqlDbType.Int) }; paras[0].Value = yyID; paras[1].Value = dxMC; paras[2].Value = classID; try { DataSet ds = wxHelper.ExecSqlReDs(strSQL, paras); if (ds != null && ds.Tables[0] != null) { if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { foreach (DataRow dr in ds.Tables[0].Rows) { model.ID = int.Parse(dr["ID"].ToString()); model.YYID = int.Parse(dr["YYID"].ToString()); model.DXMC = dr["DXMC"].ToString(); model.TMPID = int.Parse(dr["TMPID"].ToString()); model.MBMXZH = int.Parse(dr["MBMXZH"].ToString()); model.XQURL = dr["XQURL"].ToString(); model.MBID = dr["MBID"].ToString(); } } } } catch (Exception ex) { throw ex; } return model; } #endregion #region 构造微信消息Json串 /// <summary> /// 根据模板ID及组号获取微信消息json拼接信息 /// </summary> /// <param name="openid">用户唯一标识</param> /// <param name="model">微信辅助帮助类</param> /// <returns></returns> public static string GetWXjsonData(string openid, WXDataHelper model) { string sendText = string.Empty; string strSQL = string.Empty; decimal mcid = 0; int hc = 0; mcid = model.MCID; hc = model.HC; strSQL = @" SELECT DATANAME, CONTENT FROM WX_TemplateMsgsId_MX WHERE TMPID = @TMPID AND ZH = @ZH ORDER BY PX"; SqlParameter[] paras = new SqlParameter[] { new SqlParameter("@TMPID",SqlDbType.Int), new SqlParameter("@ZH",SqlDbType.Int) }; paras[0].Value = model.TMPID; paras[1].Value = model.MBMXZH; try { DataSet ds = wxHelper.ExecSqlReDs(strSQL, paras); //// 当前时间 //String now = DateTime.Now.ToString("yyyy-MM-dd HH:mm"); ////构造模板消息数据 StringBuilder dataStr = new StringBuilder(); if (ds != null && ds.Tables[0] != null) { if (ds.Tables.Count > 0 && ds.Tables[0].Rows.Count > 0) { foreach (DataRow dr in ds.Tables[0].Rows) { dataStr.Append(""" + dr["DATANAME"].ToString() + "":{"value":"" + (dr["CONTENT"].ToString() == "<time>" ? DateTime.Now.ToString("yyyy-MM-dd HH:mm") : dr["CONTENT"].ToString()) + "","color":"#173177"},"); } } dataStr = dataStr.Remove(dataStr.Length - 1, 1); } if (mcid > 0 && hc > 0) { model.XQURL = model.XQURL + "?mcid=" + mcid.ToString() + "&hc=" + hc.ToString(); } sendText = sendText = "{"touser":"" + openid + "","template_id":"" + model.MBID.ToString() + "","url":"" + model.XQURL + "","topcolor":"#FF0000","data":{" + dataStr + "}}"; } catch (Exception ex) { throw ex; } return sendText; } #endregion #region 微信消息发送记录表新增 /// <summary> /// 微信消息发送记录表新增 /// </summary> /// <param name="model">微信消息发送记录表Model</param> public static void InsertWXXXFSJLB(WX_XXFSJLB model) { string sqlStr = @"INSERT WX_XXFSJLB(YYID,OPENID,FSLY,XXLB,DWDM,YHDM,XXNR,FSSJ,FSJG,ERRORMSG) VALUES(@YYID,@OPENID,@FSLY,@XXLB,@DWDM,@YHDM,@XXNR,@FSSJ,@FSJG,@ERRORMSG)"; SqlParameter[] para = new SqlParameter[] { new SqlParameter("@YYID", model.YYID), new SqlParameter("@OPENID", model.OPENID), new SqlParameter("@FSLY", model.FSLY), new SqlParameter("@XXLB", model.XXLB), new SqlParameter("@DWDM", model.DWDM), new SqlParameter("@YHDM", model.YHDM), new SqlParameter("@XXNR", model.XXNR), new SqlParameter("@FSSJ", model.FSSJ), new SqlParameter("@FSJG", model.FSJG), new SqlParameter("@ERRORMSG", model.ERRORMSG) }; try { wxHelper.ExecSqlReInt(sqlStr, para); } catch (Exception ex) { throw ex; } } #endregion #region 获取微信基础配置信息 /// <summary> /// 获取微信基础配置信息 /// </summary> /// <param name="_connectionString">公众号对应链接串</param> /// <returns></returns> public static Sys_Config GetConfig(string _connectionString) { using (SqlConnection conn = new SqlConnection(_connectionString)) { SqlCommand comm = new SqlCommand("select *,CONVERT(varchar(30), Token_Time,121) as Token_TimeT,CONVERT(varchar(30), Ticket_Time,121) as Ticket_TimeT from sys_Config where Id = @Id", conn); comm.Parameters.AddWithValue("@Id", 1); conn.Open(); SqlDataReader sdr = comm.ExecuteReader(); Sys_Config config = new Sys_Config(); if (sdr.HasRows) { while (sdr.Read()) { config.ID = Convert.ToInt32(sdr["ID"].ToString()); config.AppID = sdr["AppID"].ToString(); config.AppSecret = sdr["AppSecret"].ToString(); config.Access_Token = sdr["Access_Token"].ToString(); config.token_Time = sdr["token_TimeT"].ToString(); config.jsapi_Ticket = sdr["jsapi_Ticket"].ToString(); config.ticket_Time = sdr["ticket_TimeT"].ToString(); if (sdr["expires_In"].ToString() != "") { config.expires_In = Convert.ToInt32(sdr["expires_In"].ToString()); } } return config; } else { return null; } } } #endregion #region 修改AccessToken /// <summary> /// 更新新的AccessToken /// </summary> /// <param name="accessToken">新的AccessToken</param> /// <param name="tokenTime">tokenTime</param> /// <param name="expiresIn">有效期(单位:s)</param> /// <param name="_connectionString"></param> public static void UpdateAccessToken(String accessToken, String tokenTime, int expiresIn, string _connectionString) { using (SqlConnection conn = new SqlConnection(_connectionString)) { SqlCommand comm = null; comm = new SqlCommand("update sys_Config set Access_token = @Access_token, Token_Time = @Token_Time, Expires_In = @Expires_In where Id = @Id", conn); comm.Parameters.AddWithValue("@Access_token", accessToken); comm.Parameters.AddWithValue("@Token_Time", tokenTime); comm.Parameters.AddWithValue("@Expires_In", expiresIn); comm.Parameters.AddWithValue("@Id", 1); conn.Open(); comm.ExecuteNonQuery(); conn.Close(); comm = null; conn.Dispose(); } } #endregion #region 发送微信模板消息 /// <summary> //发送模板消息 /// </summary> public string PostWXTemplateMsg(string toOpenId, WXDataHelper model) { //微信信息数据链接串 string _connectionString = GetDBConnectionStr(model.YYID); //获取Access_Token String Access_token = GetToken(_connectionString); String sendText = GetWXjsonData(toOpenId, model); //发送模板消息 String postURL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" + Access_token; HttpWebRequest hwr = WebRequest.Create(postURL) as HttpWebRequest; hwr.Method = "POST"; hwr.ContentType = "application/x-www-form-urlencoded"; byte[] payload; //通过UTF-8编码 payload = Encoding.UTF8.GetBytes(sendText); hwr.ContentLength = payload.Length; Stream writer = hwr.GetRequestStream(); writer.Write(payload, 0, payload.Length); writer.Close(); //获得上面URl返回的数据 var result = hwr.GetResponse() as HttpWebResponse; string strMsg = WebResponseGet(result); JavaScriptSerializer s = new JavaScriptSerializer(); Dictionary<string, object> JsonData = (Dictionary<string, object>)s.DeserializeObject(strMsg); WX_XXFSJLB m = new WX_XXFSJLB() { YYID = model.YYID, OPENID = toOpenId, FSLY = 1, XXLB = model.ID, DWDM = model.DWDM, YHDM = model.YHDM, XXNR = sendText, FSSJ = DateTime.Now, FSJG = JsonData["errcode"].ToString() == "0" ? 1 : 2, ERRORMSG = JsonData["errmsg"].ToString() }; InsertWXXXFSJLB(m); return strMsg; } #endregion #region 获取最新Access_token /// <summary> /// 获取最新Access_token /// </summary> private string GetToken(string _connectionString) { //保存获取的accessToken String accessToken = ""; //保存获取的expiresIn int expiresIn; //查询配置信息 Sys_Config config = GetConfig(_connectionString); //获取数据库中的信息 int expires_In = config.expires_In; DateTime now = DateTime.Now; DateTime token_Time = Convert.ToDateTime(config.token_Time); String AppId = config.AppID; String AppSecret = config.AppSecret; DateTime tokenTime = Convert.ToDateTime(token_Time); //获取Access_Token距离现在的时间 int secondDiff = SecondDiff(now, tokenTime); //当Access_token过期时 if (secondDiff > expires_In) { //重新获取新Access_token String tokenUtl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" + AppId + "&secret=" + AppSecret; //获取新access_token的时间(当前时间) String nowTime = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss"); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(tokenUtl); request.Method = "GET"; HttpWebResponse response = (HttpWebResponse)request.GetResponse(); string respText = ""; using (Stream resStream = response.GetResponseStream()) { StreamReader reader = new StreamReader(resStream, Encoding.Default); respText = reader.ReadToEnd(); resStream.Close(); } JavaScriptSerializer Jss = new JavaScriptSerializer(); Dictionary<string, object> respDic = (Dictionary<string, object>)Jss.DeserializeObject(respText); //获取json内容 //通过键access_token获取值 accessToken = respDic["access_token"].ToString(); //通过键expires_in获取值 expiresIn = Convert.ToInt32(respDic["expires_in"]); //新的Access_token入库 UpdateAccessToken(accessToken, nowTime, expiresIn, _connectionString); } else { //使用原有的Access_Token accessToken = config.Access_Token; } return accessToken; } #endregion /// <summary> /// 计算两个日期的时间间隔,返回的是时间间隔的日期差的总秒数 /// </summary> /// <param name="DateTime1">第一个日期和时间</param> /// <param name="DateTime2">第二个日期和时间</param> /// <returns></returns> private int SecondDiff(DateTime DateTime1, DateTime DateTime2) { int secondDiff = -1; try { TimeSpan ts1 = new TimeSpan(DateTime1.Ticks); TimeSpan ts2 = new TimeSpan(DateTime2.Ticks); TimeSpan ts = ts1.Subtract(ts2).Duration(); secondDiff = (int)ts.TotalSeconds; } catch (Exception e) { e.GetBaseException(); } return secondDiff; } /// <summary> /// 获取Response /// </summary> private string WebResponseGet(HttpWebResponse webResponse) { StreamReader responseReader = null; string responseData = ""; try { responseReader = new StreamReader(webResponse.GetResponseStream()); responseData = responseReader.ReadToEnd(); } catch { throw; } finally { webResponse.GetResponseStream().Close(); responseReader.Close(); responseReader = null; } return responseData; } }
辅助方法类
/// <summary> /// 微信消息发送记录表 /// </summary> public class WX_XXFSJLB { /// <summary> /// 所属应用ID(WX_SendMsgsYYB) /// </summary> public int YYID { get; set; } /// <summary> /// 接受消息的openid /// </summary> public string OPENID { get; set; } /// <summary> /// 发送来源(1、自动发送;2、手动发送;3、定时发送) /// </summary> public int FSLY { get; set; } /// <summary> /// 发送消息类别(MCHD_SendMsgsDX表ID) /// </summary> public int XXLB { get; set; } /// <summary> /// 发送单位代码(托盘定时发送时为null) /// </summary> public string DWDM { get; set; } /// <summary> /// 发送用户代码(托盘定时发送时为null) /// </summary> public string YHDM { get; set; } /// <summary> /// 发送消息内容 /// </summary> public string XXNR { get; set; } /// <summary> /// 发送时间 /// </summary> public DateTime FSSJ { get; set; } /// <summary> /// 发送结果(1、成功;2、失败) /// </summary> public int FSJG { get; set; } /// <summary> /// 失败原因 /// </summary> public string ERRORMSG { get; set; } } /// <summary> /// 微信消息辅助帮助实体 /// </summary> public class WXDataHelper { /// <summary> /// 消息对象ID /// </summary> public int ID { get; set; } /// <summary> /// 所属应用ID /// </summary> public int YYID { get; set; } /// <summary> /// 对象名称 /// </summary> public string DXMC { get; set; } /// <summary> /// 微信消息模板ID(TemplateMsgsId) /// </summary> public int TMPID { get; set; } /// <summary> /// 模板表TemplateMsgsId MBID /// </summary> public string MBID { get; set; } /// <summary> /// 微信消息模板内容明细组号(WX_TemplateMsgsId_MX:ZH) /// </summary> public int MBMXZH { get; set; } /// <summary> /// 详情链接的URL /// </summary> public string XQURL { get; set; } /// <summary> /// 发送用户代码 /// </summary> public string YHDM { get; set; } /// <summary> /// 发送单位代码 /// </summary> public string DWDM { get; set; } private decimal _mcid = 0; /// <summary> /// 当前操作档案的母子基本情况表ID /// </summary> public decimal MCID { get { return _mcid; } set { _mcid = value; } } private int _hc = 0; /// <summary> /// 孩次 /// </summary> public int HC { get { return _hc; } set { _hc = value; } } }
调用案例:
#region 是否推送微信模板消息 string wxxxtsyyid = ComMethod.GetXTCS("wxxxtsyyid"); //是否启用微信消息推送 0 不启用,1 启用 if (int.Parse(wxxxtsyyid) > 0) { ComSendWXMsg cs = new ComSendWXMsg(); WXDataHelper model = ComSendWXMsg.GetWxDXData(int.Parse(wxxxtsyyid), "新生儿体格评价结果", 1); if (!string.IsNullOrEmpty(model.ID.ToString()) && !string.IsNullOrEmpty(model.YYID.ToString())) { model.MCID = jbqk.mCID; model.HC = Convert.ToInt32(dataDic["hc"]); model.YHDM = dataDic["yhdm"]; model.DWDM = dataDic["txt_JCDWDM"]; if (!string.IsNullOrEmpty(jbqk.Openid)) { //"oiRm80iQn3fPLm7nOkJRccEdFT1k" cs.PostWXTemplateMsg(jbqk.Openid, model); //获取微信端前缀 String confPath = HttpContext.Current.Server.MapPath("../tconf/Conf_wx.inc"); List<string> conArr = ComMethod.Config(confPath); string Prefix = conArr[0]; //域名 Uri uri = new Uri(model.XQURL); string domainStr = uri.Host; //加密后的openid string openidStr = EnOrDecrypt.EncryptStr(jbqk.Openid); //将openid存入Cookie中 HttpContext.Current.Response.Cookies[Prefix + "_openid"].Value = openidStr; HttpContext.Current.Response.Cookies[Prefix + "_openid"].Expires = DateTime.Now.AddDays(30); HttpContext.Current.Response.Cookies[Prefix + "_openid"].Domain = domainStr; HttpContext.Current.Response.Cookies[Prefix + "_openid"].Path = "/"; //将utype存入Cookie中 HttpContext.Current.Response.Cookies[Prefix + "_utype"].Value = "jumin"; HttpContext.Current.Response.Cookies[Prefix + "_utype"].Expires = DateTime.Now.AddDays(30); HttpContext.Current.Response.Cookies[Prefix + "_utype"].Domain = domainStr; HttpContext.Current.Response.Cookies[Prefix + "_utype"].Path = "/"; //将母亲身份证号存入Cookie中 HttpContext.Current.Response.Cookies[Prefix + "_FNSFZH"].Value = jbqk.fNSFZH; HttpContext.Current.Response.Cookies[Prefix + "_FNSFZH"].Expires = DateTime.Now.AddDays(30); HttpContext.Current.Response.Cookies[Prefix + "_FNSFZH"].Domain = domainStr; HttpContext.Current.Response.Cookies[Prefix + "_FNSFZH"].Path = "/"; //将母亲姓名存入Cookie中 HttpContext.Current.Response.Cookies[Prefix + "_FNXM"].Value = HttpContext.Current.Server.UrlEncode(jbqk.fNXM); HttpContext.Current.Response.Cookies[Prefix + "_FNXM"].Expires = DateTime.Now.AddDays(30); HttpContext.Current.Response.Cookies[Prefix + "_FNXM"].Domain = domainStr; HttpContext.Current.Response.Cookies[Prefix + "_FNXM"].Path = "/"; //将儿童胎次存入Cookie中 HttpContext.Current.Response.Cookies[Prefix + "_TAICI"].Value = jbqk.eTTC.ToString(); HttpContext.Current.Response.Cookies[Prefix + "_TAICI"].Expires = DateTime.Now.AddDays(30); HttpContext.Current.Response.Cookies[Prefix + "_TAICI"].Domain = domainStr; HttpContext.Current.Response.Cookies[Prefix + "_TAICI"].Path = "/"; //将母子编号存入Cookie中 HttpContext.Current.Response.Cookies[Prefix + "_MCID"].Value = jbqk.mCID.ToString(); HttpContext.Current.Response.Cookies[Prefix + "_MCID"].Expires = DateTime.Now.AddDays(30); HttpContext.Current.Response.Cookies[Prefix + "_MCID"].Domain = domainStr; HttpContext.Current.Response.Cookies[Prefix + "_MCID"].Path = "/"; //创建cookies时间 HttpContext.Current.Response.Cookies[Prefix + "_time_jm"].Value = DateTime.Now.ToString("yyyy-MM-dd HH:mm;ss.fff"); } } } #endregion