• .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 + "
    ");
                // 结束符
                byte[] endBoundary = Encoding.ASCII.GetBytes("--" + boundary + "--
    ");
                //换行
                byte[] newLine = Encoding.ASCII.GetBytes("
    ");
                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}"
    " +
                         "Content-Type: application/octet-stream
    
    ",
                         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 = "
    --" + boundary +
                                               "
    Content-Disposition: form-data; name="{0}"" +
                                               "
    
    {1}
    ";
                        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模板消息

  • 相关阅读:
    js 控制页面跳转的5种方法
    弹性盒
    js中变量声明有var和没有var的区别
    解决Cannot read property 'style' of null中样式问题
    JS中用for循环解决重复定义的问题
    博客第一天
    jQuery 无缝轮播
    随鼠标移动
    倒计时
    轮播图
  • 原文地址:https://www.cnblogs.com/fenglingyi/p/4653443.html
Copyright © 2020-2023  润新知