.NET微信公众号开发-6.0模板消息

一.前言

为了保证用户不受到骚扰,在开发者出现需要主动提醒、通知用户时,才允许开发者在公众平台网站中模板消息库中选择模板,选择后获得模板ID,再根据模板ID向用户主动推送提醒、通知消息。这个意思也就是,我们作为微信商户,不能主动的给用户推送消息,如果这个功能完全开放,那么用户有可能会受到大量的垃圾信息,为了做一个很好的控制,微信那边给我们开放了一个模板消息,通过模板消息我们可以友好的给用户发送一些相关的消息提醒。

二.开发前的准备

1.0模板消息官方文档地址

2.0查看我们的模板消息是否申请成功。申请成功后你可以看到如下图片:

三.开始编码

一般我们在客户支付成功订单以后,会有一个支付的跳转页面,在我们前面的代码中也有相应的页面,代码如下:

<script type="text/javascript">

               //调用微信JS api 支付
               function jsApiCall()
               {
                   WeixinJSBridge.invoke(
                   ‘getBrandWCPayRequest‘,
                   <%=wxJsApiParam%>,//josn串
                    function (res)
                    {
                      if (res.err_msg == "get_brand_wcpay_request:ok")
                       {
                           var OrderId=$("#OrderId").val();
                           var orderProductName=$("#orderProductName").val();
                           var orderMoneySum=$("#orderMoneySum").val();

                            window.location.href="http://www.baidu.com/PaySkip.aspx?OrderId="+OrderId+"&orderMoneySum="+orderMoneySum+"&orderProductName="+orderProductName;//支付成功后的跳转页面

                        }else
                        {
                          WeixinJSBridge.call(‘closeWindow‘);
                        }

                     }
                    );
               }

               function callpay()
               {
                   if (typeof WeixinJSBridge == "undefined")
                   {
                       if (document.addEventListener)
                       {
                           document.addEventListener(‘WeixinJSBridgeReady‘, jsApiCall, false);
                       }
                       else if (document.attachEvent)
                       {
                           document.attachEvent(‘WeixinJSBridgeReady‘, jsApiCall);
                           document.attachEvent(‘onWeixinJSBridgeReady‘, jsApiCall);
                       }
                   }
                   else
                   {
                       jsApiCall();
                   }
               }

           </script>

在上一篇,微信支付成功后,我们有这样一个支付跳转页面,在这个支付跳转页面里,我们可以写一些我们自己的业务逻辑,比如我们今天的主角,模板消息提醒:直接上代码

                    #region 发送支付成功的消息
                    ErrorMessage errorMessage;

                    string username = System.Configuration.ConfigurationManager.AppSettings["weixinid"].ToString();
                    string templateId = System.Configuration.ConfigurationManager.AppSettings["templateId"].ToString();

                    string first = "您已成功付费,欢迎下次光临。";
                    string orderMoneySum = Request["orderMoneySum"] ?? "0";
                    string orderProductName = Request["orderProductName"] ?? "有位停车付费系统测试";
                    string Remark = "如有问题请致电400-6238-136或直接在微信留言,我们将第一时间为您服务!";
                    Color color = Color.Red;
                    Tuple<string, string, Color>[] data = new Tuple<string, string, Color>[]{
                    new Tuple<string,string,Color>("first",first,Color.Blue),
                    new Tuple<string,string,Color>("orderMoneySum",orderMoneySum,Color.Red),
                    new Tuple<string,string,Color>("orderProductName",orderProductName,Color.Orange),
                    new Tuple<string,string,Color>("Remark",Remark,Color.Green)
                };

                    long msgId = TemplateMessage.Send(username, openId, templateId, "", color, data, out errorMessage);
                    if (errorMessage.IsSuccess)
                    {
                        Response.Write("errorMessage " + errorMessage.errmsg + "<br/>");
                    }
                    else
                    {
                        Response.Write("errorMessage.errmsg: " + errorMessage.errmsg + "<br/>");
                    }
                    #endregion

从上面的代码中我们可以看到TemplateMessage.Send()这个方法是我们发送消息的关键,我们来看看这个方法是怎样的:

        #region 发送模板消息
        /// <summary>
        /// 发送模板消息
        /// </summary>
        /// <param name="userName">公众号</param>
        /// <param name="touser">接收消息的账号</param>
        /// <param name="templateId">模板id</param>
        /// <param name="detailUrl">详情地址</param>
        /// <param name="topColor">顶端颜色</param>
        /// <param name="data">数据</param>
        /// <param name="errorMessage">返回发送是否成功</param>
        /// <returns>返回消息id;如果发送失败,返回-1。</returns>
        public static long Send(string userName, string touser, string templateId, string detailUrl, Color topColor,
            Tuple<string, string, Color>[] data, out ErrorMessage errorMessage)
        {
            errorMessage = new ErrorMessage(ErrorMessage.ExceptionCode, "");
            long id = -1;
            //校验参数
            if (string.IsNullOrWhiteSpace(touser))
            {
                errorMessage.errmsg = "接收消息的账号不能为空。";
                return id;
            }
            if (string.IsNullOrWhiteSpace(templateId))
            {
                errorMessage.errmsg = "模板id不能为空。";
                return id;
            }
            if (data == null || data.Length == 0)
            {
                errorMessage.errmsg = "模板数据不能为空。";
                return id;
            }
            foreach (Tuple<string, string, Color> item in data)
            {
                if (string.IsNullOrWhiteSpace(item.Item1) || string.IsNullOrWhiteSpace(item.Item2))
                {
                    errorMessage.errmsg = "模板数据不能为空。";
                    return id;
                }
            }
            //获取许可令牌
            AccessToken token = AccessToken.Get(userName);
            if (token == null)
            {
                errorMessage.errmsg = "获取许可令牌失败。";
                return id;
            }
            string url = string.Format(urlForSending, token.access_token);
            //生成待发送的数据
            dynamic postData = new ExpandoObject();
            postData.touser = touser;
            postData.template_id = templateId;
            postData.url = detailUrl ?? string.Empty;
            postData.topcolor = Utility.GetColorString(topColor);
            postData.data = new ExpandoObject();
            IDictionary<string, object> dataDict = (IDictionary<string, object>)postData.data;
            foreach (Tuple<string, string, Color> item in data)
            {
                dataDict.Add(item.Item1, new { value = item.Item2, color = Utility.GetColorString(item.Item3) });
            }
            string json = JsonConvert.SerializeObject(postData);
            //发送数据
            string responseContent;
            if (!HttpHelper.Request(url, out responseContent, httpMethod, json))
            {
                errorMessage.errmsg = "提交数据到微信服务器失败。";
                return id;
            }
            //解析结果
            JObject jo = JObject.Parse(responseContent);
            JToken jt;
            if (jo.TryGetValue("errcode", out jt) && jo.TryGetValue("errmsg", out jt))
            {
                errorMessage.errcode = (int)jo["errcode"];
                errorMessage.errmsg = (string)jo["errmsg"];
                if (jo.TryGetValue("msgid", out jt))
                    id = (long)jt;
            }
            else
                errorMessage.errmsg = "解析返回结果失败。";
            return id;
        }
        #endregion
 AccessToken token = AccessToken.Get(userName);获取许可令牌上一篇文章中我们已经说过这个类,这里就不多说了,HttpHelper帮助类的代码如下:

   /// <summary>
    /// HttpHelper:http请求与响应辅助类
    /// </summary>
    public static class HttpHelper
    {
        /// <summary>
        /// 向微信服务器发送请求时的编码
        /// </summary>
        public static readonly Encoding RequestEncoding = Encoding.UTF8;
        /// <summary>
        /// 微信服务器响应的编码
        /// </summary>
        public static readonly Encoding ResponseEncoding = Encoding.UTF8;

        /// <summary>
        /// 向微信服务器提交数据,并获取微信服务器响应的数据
        /// </summary>
        /// <param name="url">服务器地址</param>
        /// <param name="responseData">返回响应数据</param>
        /// /// <param name="httpMethod">http方法</param>
        /// <param name="data">数据</param>
        /// <returns>返回是否提交成功</returns>
        public static bool Request(string url, out byte[] responseData,
            string httpMethod = WebRequestMethods.Http.Get, byte[] data = null)
        {
            bool success = false;
            responseData = null;
            Stream requestStream = null;
            HttpWebResponse response = null;
            Stream responseStream = null;
            MemoryStream ms = null;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = httpMethod;
                if (data != null && data.Length > 0)
                {
                    request.ContentLength = data.Length;
                    requestStream = request.GetRequestStream();
                    requestStream.Write(data, 0, data.Length);
                }
                response = (HttpWebResponse)request.GetResponse();
                //由于微信服务器的响应有时没有正确设置ContentLength,这里不检查ContentLength
                //if (response.ContentLength > 0)
                {
                    ms = new MemoryStream();
                    responseStream = response.GetResponseStream();
                    int bufferLength = 2048;
                    byte[] buffer = new byte[bufferLength];
                    int size = responseStream.Read(buffer, 0, bufferLength);
                    while (size > 0)
                    {
                        ms.Write(buffer, 0, size);
                        size = responseStream.Read(buffer, 0, bufferLength);
                    }
                    responseData = ms.ToArray();
                }
                success = true;
            }
            finally
            {
                if (requestStream != null)
                    requestStream.Close();
                if (responseStream != null)
                    responseStream.Close();
                if (ms != null)
                    ms.Close();
                if (response != null)
                    response.Close();
            }
            return success;
        }

        /// <summary>
        /// 向微信服务器提交数据,并获取微信服务器响应的数据
        /// </summary>
        /// <param name="url">服务器地址</param>
        /// <param name="responseData">返回响应数据</param>
        /// /// <param name="httpMethod">http方法</param>
        /// <param name="data">数据</param>
        /// <returns>返回是否提交成功</returns>
        public static bool Request(string url, out byte[] responseData,
            string httpMethod = WebRequestMethods.Http.Get, string data = null)
        {
            byte[] bytes = string.IsNullOrEmpty(data) ? null : RequestEncoding.GetBytes(data);
            return Request(url, out responseData, httpMethod, (byte[])bytes);
        }

        /// <summary>
        /// 向微信服务器提交数据,并获取微信服务器响应的内容
        /// </summary>
        /// <param name="url">服务器地址</param>
        /// <param name="responseContent">返回响应内容</param>
        /// /// <param name="httpMethod">http方法</param>
        /// <param name="data">数据</param>
        /// <returns>返回是否提交成功</returns>
        public static bool Request(string url, out string responseContent,
            string httpMethod = WebRequestMethods.Http.Get, byte[] data = null)
        {
            byte[] responseData;
            responseContent = string.Empty;
            bool success = Request(url, out responseData, httpMethod, data);
            if (success && responseData != null && responseData.Length > 0)
                responseContent = ResponseEncoding.GetString(responseData);
            return success;
        }

        /// <summary>
        /// 向微信服务器提交数据,并获取微信服务器响应的内容
        /// </summary>
        /// <param name="url">服务器地址</param>
        /// <param name="responseContent">返回响应内容</param>
        /// /// <param name="httpMethod">http方法</param>
        /// <param name="data">数据</param>
        /// <returns>返回是否提交成功</returns>
        public static bool Request(string url, out string responseContent,
            string httpMethod = WebRequestMethods.Http.Get, string data = null)
        {
            byte[] bytes = string.IsNullOrEmpty(data) ? null : RequestEncoding.GetBytes(data);
            return Request(url, out responseContent, httpMethod, (byte[])bytes);
        }

        /// <summary>
        /// 向微信服务器提交数据
        /// </summary>
        /// <param name="url">服务器地址</param>
        /// /// <param name="httpMethod">http方法</param>
        /// <param name="data">数据</param>
        /// <returns>返回是否提交成功</returns>
        public static bool Request(string url, string httpMethod = WebRequestMethods.Http.Get, byte[] data = null)
        {
            bool success = false;
            Stream requestStream = null;
            HttpWebResponse response = null;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = httpMethod;
                if (data != null && data.Length > 0)
                {
                    request.ContentLength = data.Length;
                    requestStream = request.GetRequestStream();
                    requestStream.Write(data, 0, data.Length);
                }
                response = (HttpWebResponse)request.GetResponse();
                success = true;
            }
            finally
            {
                if (requestStream != null)
                    requestStream.Close();
                if (response != null)
                    response.Close();
            }
            return success;
        }

        /// <summary>
        /// 组合url,发送数据,然后返回响应字符串
        /// </summary>
        /// <param name="urlFormat">url格式字符串,第一个参数为userName获取到的许可令牌,然后依次为parameters中的参数</param>
        /// <param name="userName">公众号</param>
        /// <param name="urlParameters">参数</param>
        /// <param name="httpMethod">执行请求的http方法</param>
        /// <param name="data">请求的内容</param>
        /// <returns>返回响应内容;如果请求失败,或者发生错误,返回空字符串</returns>
        public static string RequestResponseContent(string urlFormat, string userName, IEnumerable<object> urlParameters = null, string httpMethod = WebRequestMethods.Http.Get, string data = null)
        {
            string responseContent = string.Empty;
            AccessToken token = AccessToken.Get(userName);
            if (token == null)
                return responseContent;
            string url;
            if (urlParameters == null)
                url = string.Format(urlFormat, token.access_token);
            else
            {
                List<object> paramList = new List<object>(urlParameters);
                paramList.Insert(0, token.access_token);
                url = string.Format(urlFormat, paramList.ToArray());
            }
            HttpHelper.Request(url, out responseContent, httpMethod, (string)data);
            return responseContent;
        }

        /// <summary>
        /// 组合url,发送数据,然后返回响应的错误消息。
        /// 注:错误消息不一定代表失败或者错误。
        /// </summary>
        /// <param name="urlFormat">url格式字符串,第一个参数为userName获取到的许可令牌,然后依次为parameters中的参数</param>
        /// <param name="userName">公众号</param>
        /// <param name="urlParameters">参数</param>
        /// <param name="httpMethod">执行请求的http方法</param>
        /// <param name="data">请求的内容</param>
        /// <returns>返回响应的错误消息</returns>
        public static ErrorMessage RequestErrorMessage(string urlFormat, string userName, IEnumerable<object> urlParameters = null, string httpMethod = WebRequestMethods.Http.Get, string data = null)
        {
            string responseContent = RequestResponseContent(urlFormat, userName, urlParameters, httpMethod, data);
            if (string.IsNullOrWhiteSpace(responseContent))
                return new ErrorMessage(ErrorMessage.ExceptionCode, "请求失败。");
            else if (ErrorMessage.IsErrorMessage(responseContent))
                return ErrorMessage.Parse(responseContent);
            else
                return new ErrorMessage(ErrorMessage.ExceptionCode, "解析响应失败。");
        }

        /// <summary>
        /// 组合url,发送数据,然后返回结果。
        /// 注:结果为需要解析的类。
        /// </summary>
        /// <typeparam name="T">返回结果的类型</typeparam>
        /// <param name="urlFormat">url格式字符串,第一个参数为userName获取到的许可令牌,然后依次为parameters中的参数</param>
        /// <param name="userName">公众号</param>
        /// <param name="errorMessage">返回请求是否成功</param>
        /// <param name="urlParameters">参数</param>
        /// <param name="httpMethod">执行请求的http方法</param>
        /// <param name="data">请求的内容</param>
        /// <returns>返回结果;如果请求失败,或者发生错误,返回null。</returns>
        public static T RequestParsableResult<T>(string urlFormat, string userName, out ErrorMessage errorMessage, IEnumerable<object> urlParameters = null, string httpMethod = WebRequestMethods.Http.Get, string data = null)
            where T : IParsable, new()
        {
            T result = default(T);
            errorMessage = new ErrorMessage(ErrorMessage.ExceptionCode, "请求失败。");
            string responseContent = RequestResponseContent(urlFormat, userName, urlParameters, httpMethod, data);
            if (string.IsNullOrWhiteSpace(responseContent))
                return result;
            if (ErrorMessage.IsErrorMessage(responseContent))
                errorMessage = ErrorMessage.Parse(responseContent);
            else
            {
                try
                {
                    result = Utility.Parse<T>(responseContent);
                    if (result != null)
                        errorMessage = new ErrorMessage(ErrorMessage.SuccessCode, "请求成功。");
                    else
                        errorMessage = new ErrorMessage(ErrorMessage.ExceptionCode, "解析失败。");
                }
                catch
                {
                    errorMessage = new ErrorMessage(ErrorMessage.ExceptionCode, "解析失败。");
                }
            }
            return result;
        }

        /// <summary>
        /// 组合url,发送数据,然后返回结果。
        /// 注:结果为已知的简单值类型。
        /// </summary>
        /// <typeparam name="T">返回结果的类型</typeparam>
        /// <param name="urlFormat">url格式字符串,第一个参数为userName获取到的许可令牌,然后依次为parameters中的参数</param>
        /// <param name="userName">公众号</param>
        /// <param name="propertyNameInJson">返回结果在json中的键名</param>
        /// <param name="errorMessage">返回请求是否成功</param>
        /// <param name="urlParameters">参数</param>
        /// <param name="httpMethod">执行请求的http方法</param>
        /// <param name="data">请求的内容</param>
        /// <returns>返回结果;如果请求失败,或者发生错误,返回default(T)。</returns>
        public static T RequestValueTypeResult<T>(string urlFormat, string userName, string propertyNameInJson, out ErrorMessage errorMessage, IEnumerable<object> urlParameters = null, string httpMethod = WebRequestMethods.Http.Get, string data = null)
            where T : struct
        {
            errorMessage = new ErrorMessage(ErrorMessage.ExceptionCode, "请求失败。");
            string responseContent = RequestResponseContent(urlFormat, userName, urlParameters, httpMethod, data);
            return ConvertValueTypeResult<T>(responseContent, propertyNameInJson, out errorMessage);
        }

        /// <summary>
        /// 获取值类型的结果
        /// </summary>
        /// <typeparam name="T">返回结果的类型</typeparam>
        /// <param name="responseContent">响应内容</param>
        /// <param name="propertyNameInJson">返回结果在json中的键名</param>
        /// <param name="errorMessage">返回请求是否成功</param>
        /// <returns>返回结果;如果请求失败,或者发生错误,返回default(T)。</returns>
        private static T ConvertValueTypeResult<T>(string responseContent, string propertyNameInJson, out ErrorMessage errorMessage)
            where T : struct
        {
            if (string.IsNullOrWhiteSpace(responseContent))
            {
                errorMessage = new ErrorMessage(ErrorMessage.ExceptionCode, "请求失败。");
                return default(T);
            }
            if (ErrorMessage.IsErrorMessage(responseContent))
                errorMessage = ErrorMessage.Parse(responseContent);
            else
                errorMessage = new ErrorMessage(ErrorMessage.SuccessCode, "请求成功。");
            JObject jo = JObject.Parse(responseContent);
            JToken jt;
            if (jo.TryGetValue(propertyNameInJson, out jt))
                return ConvertValueTypeResult<T>((string)jt);
            else
                return default(T);
        }

        /// <summary>
        /// 获取值类型的结果
        /// </summary>
        /// <typeparam name="T">返回结果的类型</typeparam>
        /// <param name="responseContent">响应内容</param>
        /// <param name="propertyNameInJson">返回结果在json中的键名</param>
        /// <param name="errorMessage">返回请求是否成功</param>
        /// <returns>返回结果;如果请求失败,或者发生错误,返回default(T)。</returns>
        private static T ConvertValueTypeResult<T>(string value)
            where T : struct
        {
            Type type = typeof(T);
            if (type.IsEnum)
                return (T)Enum.Parse(type, value);
            else if (type == typeof(sbyte))
                return (T)(object)Convert.ToSByte(value);
            else if (type == typeof(byte))
                return (T)(object)Convert.ToByte(value);
            else if (type == typeof(char))
                return (T)(object)Convert.ToChar(value);
            else if (type == typeof(short))
                return (T)(object)Convert.ToInt16(value);
            else if (type == typeof(ushort))
                return (T)(object)Convert.ToUInt16(value);
            else if (type == typeof(int))
                return (T)(object)Convert.ToInt32(value);
            else if (type == typeof(uint))
                return (T)(object)Convert.ToUInt32(value);
            else if (type == typeof(long))
                return (T)(object)Convert.ToInt64(value);
            else if (type == typeof(ulong))
                return (T)(object)Convert.ToUInt64(value);
            else if (type == typeof(float))
                return (T)(object)Convert.ToSingle(value);
            else if (type == typeof(double))
                return (T)(object)Convert.ToDouble(value);
            else if (type == typeof(decimal))
                return (T)(object)Convert.ToDecimal(value);
            else if (type == typeof(bool))
                return (T)(object)Convert.ToBoolean(value);
            else
                throw new ArgumentException("不支持的值类型。");
        }

        /// <summary>
        /// 向微信服务器提交数据
        /// </summary>
        /// <param name="url">服务器地址</param>
        /// /// <param name="httpMethod">http方法</param>
        /// <param name="data">数据</param>
        /// <returns>返回是否提交成功</returns>
        public static bool Request(string url, string httpMethod = WebRequestMethods.Http.Get, string data = null)
        {
            byte[] bytes = string.IsNullOrEmpty(data) ? null : RequestEncoding.GetBytes(data);
            return Request(url, httpMethod, (byte[])bytes);
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="url">服务器地址</param>
        /// <param name="filename">文件名(不包含路径)</param>
        /// <param name="fileData">文件数据</param>
        /// <param name="formData">表单数据</param>
        /// <returns>返回服务器的响应字符串</returns>
        public static string Upload(string url, string filename, byte[] fileData, NameValueCollection formData = null)
        {
            string responseContent = string.Empty;
            if (string.IsNullOrWhiteSpace(url) || string.IsNullOrWhiteSpace(filename) || fileData == null || fileData.Length == 0)
                return responseContent;
            // 边界符
            string boundary = "AaB03xAaB03x";
            // 开始边界符
            byte[] beginBoundary = Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
            // 结束符
            byte[] endBoundary = Encoding.ASCII.GetBytes("--" + boundary + "--\r\n");
            //换行
            byte[] newLine = Encoding.ASCII.GetBytes("\r\n");
            MemoryStream ms = null;
            Stream stream = null;
            HttpWebResponse response = null;
            StreamReader sr = null;
            try
            {
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = WebRequestMethods.Http.Post;
                request.ContentType = "multipart/form-data; boundary=" + boundary;
                // 写入文件
                string header = string.Format("Content-Disposition: form-data; filename=\"{0}\"\r\n" +
                     "Content-Type: application/octet-stream\r\n\r\n",
                     filename);
                byte[] headerbytes = Encoding.UTF8.GetBytes(header);
                ms = new MemoryStream();
                ms.Write(beginBoundary, 0, beginBoundary.Length);
                ms.Write(headerbytes, 0, headerbytes.Length);
                ms.Write(fileData, 0, fileData.Length);
                // 写入表单数据
                if (formData != null && formData.Count > 0)
                {
                    var formItem = "\r\n--" + boundary +
                                           "\r\nContent-Disposition: form-data; name=\"{0}\"" +
                                           "\r\n\r\n{1}\r\n";
                    foreach (string key in formData.Keys)
                    {
                        string value = formData[key];
                        byte[] bytes = Encoding.UTF8.GetBytes(string.Format(formItem, key, value));
                        ms.Write(bytes, 0, bytes.Length);
                    }
                }
                //写入结束边界符
                ms.Write(newLine, 0, newLine.Length);
                ms.Write(endBoundary, 0, endBoundary.Length);
                request.ContentLength = ms.Length;
                stream = request.GetRequestStream();
                stream.Write(ms.ToArray(), 0, (int)ms.Length);
                //获取响应
                response = (HttpWebResponse)request.GetResponse();
                sr = new StreamReader(response.GetResponseStream(), HttpHelper.ResponseEncoding);
                responseContent = sr.ReadToEnd();
            }
            finally
            {
                if (ms != null)
                    ms.Close();
                if (stream != null)
                    stream.Close();
                if (sr != null)
                    sr.Close();
                if (response != null)
                    response.Close();
            }
            return responseContent;
        }

        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="url">服务器地址</param>
        /// <param name="pathname">包含路径的文件名</param>
        /// <param name="formData">表单数据</param>
        /// <returns>返回服务器的响应字符串</returns>
        public static string Upload(string url, string pathname, NameValueCollection formData = null)
        {
            string filename = Path.GetFileName(pathname);
            byte[] data = null;
            FileStream fs = null;
            MemoryStream ms = null;
            try
            {
                fs = new FileStream(pathname, FileMode.Open, FileAccess.Read);
                ms = new MemoryStream();
                int bufferLength = 2048;
                byte[] buffer = new byte[bufferLength];
                int size = fs.Read(buffer, 0, bufferLength);
                while (size > 0)
                {
                    ms.Write(buffer, 0, size);
                    size = fs.Read(buffer, 0, bufferLength);
                }
                data = ms.ToArray();
            }
            finally
            {
                if (fs != null)
                    fs.Close();
                if (ms != null)
                    ms.Close();
            }
            return Upload(url, filename, data, formData);
        }
    }

HttpHelper

三.最终效果如下:

四.微信公众号开发系列导航

1.0初始微信公众号

2.0创建自定义菜单

3.0查询自定义菜单

4.0公众号消息处理

5.0微信支付

6.0模板消息

如果您看完本篇文章感觉不错,请点击左上角的【关注】来支持一下博主,谢谢!

如果您看完本篇文章感觉不错,请点击右下角的 【 推荐 】



作者:枫伶忆

QQ: 616931

出处:http://www.cnblogs.com/fenglingyi

声明:本文版权归作者和博客园共有,未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利


时间: 2024-10-11 13:15:01

.NET微信公众号开发-6.0模板消息的相关文章

.NET微信公众号开发-4.0公众号消息处理

一.前言 微信公众平台的消息处理还是比较完善的,有最基本的文本消息,到图文消息,到图片消息,语音消息,视频消息,音乐消息其基本原理都是一样的,只不过所post的xml数据有所差别,在处理消息之前,我们要认真阅读,官方给我们的文档:http://mp.weixin.qq.com/wiki/14/89b871b5466b19b3efa4ada8e577d45e.html.首先我们从最基本的文本消息处理开始. <xml> <ToUserName><![CDATA[toUser]]&

.NET微信公众号开发-5.0微信支付

一.前言 在开始做这个功能之前,我们要做的第一件事情就是思考,如何做这个微信支付,从哪里开始,从哪里入手,官方的sdk说明什么的,有没有什么官方的demo,还有就是老板给我的一些资料齐全不,那些要申请的接口什么的都有没有. 经过自己的一些探索,在老板的催促下终于硬着头皮做完了这个,很坑很坑的微信支付,在此做一些总结,希望对你们有所帮助,本人能力有限,如果有什么说的不好,希望大家多多包涵. 二.开发前准备. 1.0微信支付官方开发者文档 2.0官方demo下载 我们用c#所以选择.net版本 不过

.NET微信公众号开发-2.0创建自定义菜单

一.前言 开发之前,我们需要阅读官方的接口说明文档,不得不吐槽一下,微信的这个官方文档真的很烂,但是,为了开发我们需要的功能,我们也不得不去看这些文档. 接口文档地址:http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 看了这些个文档,基本意思明白了,就是我们把我们要创建的菜单创建好,post到微信的服务器上面,微信服务器然后给我们一些状态码,从而判断我们的菜单是否创建成功,只是在发送json数据以前我们要做

NET微信公众号开发-5.0微信支付(待测试)

开发前准备. 1.0微信支付官方开发者文档 2.0官方demo下载 我们用c#所以选择.net版本 不过这个官方的demo根本跑步起来 3.0官方demo运行起来解决方案 4.0微信支付官方.net版之坑你没商量 5.0开发前的微信公众平台的一些配置,请务必认真检查配置. 编码 做好了这些准备工作之后,我们知道微信支付有两种,1.原生态的,2.jsapi直接调用的,我项目中用到的是第二种 经过自己的一些业务逻辑处理,来到了我们的订单详情页面,现在需要去点击我们的支付按钮去支付,支付页面pay.a

微信公众号开发(2)---消息的接收发送

在微信公众号开发(1)中,我们进行了GET请求方法的开发编写,能够使微信与我们的服务器进行了关系的绑定,接下来我们进行开发接收用户消息与一些事件的回复:      开发必要了解:在我们微信与我们的服务器进行了关系的绑定后,微信会将用户所发过来的消息以及事件会以XML的格式以POST请求的方式发送给我们的服务器,所以我们需要开发POST请求的接口,接收用户的消息,我们可以根据用户的消息进行一些关键字回复,以及关注后的回复推送,微信事件里有很多功能,这里只进行开发关键字回复以及关注事件,其他的顺藤摸

JAVA微信公众号通过openid发送模板消息~

1,问题产生 在微信公众号开发过程中,我们有时候做不同权限的时候,比如在注册的时候,需要审核,然后我们要想办法让对方知道审核的结果.这时候我们可以通过模板消息来通知. 2,第一步,首先在微信公众号上获取模板消息 首先,登录微信公众平台,看有没有模板消息这一块,没有的话点击添加功能插件,去添加,这里就省略不说了,这个主要就是选择你公众号的行业对应的模板消息,然后通过审核之后就可以使用了,说是几个工作日 但是一般很快就审核通过的. 有模板消息之后点进来,对应自己所需要的模板消息进行添加,比如,我添加

微信公众号助手如何设置模板消息推送?

说到运营微信服务号,其目的自然是广告推广,通过微信关注粉丝获取商业价值,而广告推广的主要途径是模块链接实现价值的核心在于模板消息. 你想想如果看到一条关于"投资策略,消息提醒,预约通知"的消息,引起了客户的注意,点击量就高,而且纷纷留言服务很周到! A君:这是什么消息提醒? B君:服务号具有模板消息功能,推送的这条是模板消息. A君:有什么优势? B君:模板消息群发能够让信息第一时间送达客户手机,保障信息的及时性以及安全性. 使用鱼塘软件的模板消息群发,能够很好地跟踪.回访客户,聆听他

微信公众号开发(152)——客服消息发送卡券

本文介绍如何使用微信公众平台客服消息发送接口来发送卡券给用户. 一.卡券格式 卡券的json格式如下 { "touser":"OPENID", "msgtype":"wxcard", "wxcard":{ "card_id":"123dsdajkasd231jhksad" } } 其中,msgtype为wxcard,而card_id为卡券 ID 二.代码实现 使用方倍

微信公众号开发系列导航

 1.0.NET微信公众号开发-1.0初始微信公众号 1.0.NET微信公众号开发-1.0初始微信公众号 2.0.NET微信公众号开发-2.0创建自定义菜单  2.0.NET微信公众号开发-2.0创建自定义菜单 3.0.NET微信公众号开发-3.0查询自定义菜单  3.0.NET微信公众号开发-3.0查询自定义菜单 4.0.NET微信公众号开发-4.0公众号消息处理  4.0.NET微信公众号开发-4.0公众号消息处理 5.0.NET微信公众号开发-5.0微信支付  5.0.NET微信公众号开发