微信公众号第三方开发之六添加永久图片素材

时间:2022-08-31 22:33:14

        想要新增图文素材,就必须先有图片素材。那么微信上传永久图片素材又是怎么操作的呢?

        根据微信文档说明:

微信公众号第三方开发之六添加永久图片素材

        重点在于整合media参数,我的代码如下:

微信公众号第三方开发之六添加永久图片素材

        然后发布,测试。微信返回:{"errcode":41005,"errmsg":"mediadata missing....}        41005=缺少多媒体文件数据

        仔细查看代码,可以得知,media参数我只是把文件的名称传递过去,并没有吧本地文件传递过去,那么,知道了却不知道这个文件数据到底是怎么传递出去的呢?

 

        继续百度ing.....


        发现很多网友也是遇到了这个问题,最后又反复查看大神sdk中post请求的写法,重新定义了api接口和实体类,发送创建图片接口,如下:

 

        1、实体类:

    public classResponseNewsModel :WxJsonResult

    {

        public string media_id {get;set;}//新增永久素材返回的值

        public string url {get;set;}//新增永久图片返回url

    }

 

        ///<summary>

        ///新增其他类型永久素材图片+视频+语音

        ///</summary>

        ///<paramname="accessToken">授权方的access_token</param>

        ///<paramname="accessToken">媒体文件的类型imagevideovoice</param>

        ///<returns>{"media_id":MEDIA_ID",url": "http://mmbiz.qpic.cn/mmbiz/gLO17UPS6FS2xsypf378iaNhWacZ1G1UplZYWEYfwvuU6Ont96b1roYsCNFwaRrSaKTPCUdBK9DgEHicsKwWCBRQ/0" } 新增的图文消息素材的media_id,新增的图片素材的图片URL(仅新增图片素材时会返回该字段)</returns>

        public static ResponseNewsModel addWeixinOpenImg(stringaccessToken,string type,Dictionary<string,string>postData)

        {

            string urlFormat ="https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={0}&type="+type;

 

            return CommonJsonSend.SendFile<ResponseNewsModel>(accessToken,urlFormat, postData, WxConfig.TIME_OUT);

        }

 

        为了保证代码简洁,这里的很多方法写法都是参考原有的。

       2、 sendFile方法:

        ///<summary>

        ///这个接口是专门上传媒体文件请求向需要AccessTokenAPI发送消息的公共方法

        ///</summary>

        ///<paramname="accessToken">这里的AccessToken是通用接口的AccessToken,非OAuth的。如果不需要,可以为null,此时urlFormat不要提供{0}参数</param>

        ///<paramname="urlFormat"></param>

        ///<paramname="data">如果是Get方式,可以为null</param>

        ///<paramname="timeOut">代理请求超时时间(毫秒)</param>

        ///<returns></returns>

        public staticT SendFile<T>(string accessToken,stringurlFormat,Dictionary<string,stringfileData, inttimeOut =WxConfig.TIME_OUT)

        {

            varurl = string.IsNullOrEmpty(accessToken) ? urlFormat:string.Format(urlFormat, accessToken);           

            returnPost.PostFileGetJson<T>(url,null,fileData,null, timeOut: timeOut);

        }

 

       3、最后post发送数据方法【其他接口如转换实体类请参照原大神博客!】:

        ///<summary>

        ///发起Post请求

        ///</summary>

        ///<typeparamname="T">返回数据类型(Json对应的实体)</typeparam>

        ///<paramname="url">请求Url</param>

        ///<paramname="cookieContainer">CookieContainer,如果不需要则设为null</param>

        ///<paramname="timeOut">代理请求超时时间(毫秒)</param>

        ///<returns></returns>

        public static T PostFileGetJson<T>(string url, CookieContainer cookieContainer =null,Dictionary<string,string> fileDictionary =null,Encoding encoding =null,int timeOut =WxConfig.TIME_OUT)

        {

            string returnText = HttpUtility.RequestUtility.HttpPost(url,cookieContainer,null, fileDictionary,null,encoding, timeOut: timeOut);

            varresult = GetResult<T>(returnText);

            returnresult;

        }

 

       4、post方法:

        ///<summary>

        ///使用Post方法获取字符串结果

        ///</summary>

        ///<paramname="url"></param>

        ///<paramname="cookieContainer"></param>

        ///<paramname="postStream"></param>

        ///<paramname="fileDictionary">需要上传的文件,Key:对应要上传的NameValue:本地文件名</param>

        ///<paramname="timeOut"></param>

        ///<returns></returns>

        public static string HttpPost(string url,CookieContainer cookieContainer =null,Stream postStream =null,Dictionary<string,string> fileDictionary = null,stringrefererUrl =null,Encoding encoding =null,int timeOut = WxConfig.TIME_OUT)

        {

            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);

           request.Method ="POST";

           request.Timeout = timeOut;

 

           #region处理Form表单文件上传

            varformUploadFile = fileDictionary !=null&& fileDictionary.Count > 0;//是否用Form上传文件

            if(formUploadFile)

            {

               //通过表单上传文件

               postStream =new MemoryStream();

 

                stringboundary ="----" +DateTime.Now.Ticks.ToString("x");

               //byte[] boundarybytes =Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

               string formdataTemplate ="\r\n--" + boundary +"\r\nContent-Disposition: form-data; name=\"{0}\";filename=\"{1}\"\r\nContent-Type:application/octet-stream\r\n\r\n";

 

               foreach (var file in fileDictionary)

               {

                   try

                   {

                       varfileName = file.Value;

 

                       //准备文件流

                       using(varfileStream = FileHelper.GetFileStream(fileName))

                       {

                           var formdata =string.Format(formdataTemplate, file.Key,/*fileName*/Path.GetFileName(fileName));

                           var formdataBytes =Encoding.ASCII.GetBytes(postStream.Length== 0 ? formdata.Substring(2, formdata.Length - 2) : formdata);//第一行不需要换行

                           postStream.Write(formdataBytes,0, formdataBytes.Length);

 

                           //写入文件

                           byte[] buffer =newbyte[1024];

                           int bytesRead = 0;

                           while((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)

                           {

                               postStream.Write(buffer, 0, bytesRead);

                           }

                       }

                   }

                    catch(Exception ex)

                   {

                       throw ex;

                   }

               }

               //结尾

               var footer =Encoding.ASCII.GetBytes("\r\n--" + boundary +"--\r\n");

               postStream.Write(footer, 0, footer.Length);

 

               request.ContentType =string.Format("multipart/form-data; boundary={0}",boundary);

            }

            else

            {

               request.ContentType ="application/x-www-form-urlencoded";

            }

           #endregion

 

           request.ContentLength = postStream !=null? postStream.Length : 0;

           request.Accept ="text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";

            request.KeepAlive =true;

 

            if(!string.IsNullOrEmpty(refererUrl))

            {

               request.Referer = refererUrl;

            }

           request.UserAgent ="Mozilla/5.0 (Windows NT 6.1;WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57Safari/537.36";

           

           #region输入二进制流

            if(postStream !=null)

            {

               postStream.Position = 0;

 

               //直接写入流

               Stream requestStream = request.GetRequestStream();

 

               byte[] buffer =newbyte[1024];

               int bytesRead = 0;

               while ((bytesRead =postStream.Read(buffer, 0, buffer.Length)) != 0)

               {

                   requestStream.Write(buffer, 0, bytesRead);

               }

               postStream.Close();//关闭文件访问

            }

           #endregion

 

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            using(Stream responseStream = response.GetResponseStream())

            {

               using (StreamReadermyStreamReader = newStreamReader(responseStream,encoding ??Encoding.GetEncoding("utf-8")))

               {

                   string retString =myStreamReader.ReadToEnd();

                   return retString;

               }

            }

        }


 5、最后测试调用:

public string addImg(){

            string filepath = Server.MapPath("~/images/maxlaw.png");

            stringtype ="image";

            Dictionary<string,string>fileData =newDictionary<string,string>();

           fileData.Add("media",filepath);//事先写好参数

            ResponseNewsModel imgData =DoWeixinOpenApi.addWeixinOpenImg(Golbal_authorizer_accessToken,type, fileData);

            if (imgData.errmsg !="ok")

            {

               FileHelper.LogToTxt("发生什么错误了!" +imgData.errmsg);

            }

            FileHelper.LogToTxt("上传永久图片素材测试啊:::"+ imgData.media_id + "<br>地址是:::" + imgData.url);

            return"ok";

 }


        打开日志查看,返回结果:


上传永久素材测试啊:::YKeHO6zG3cS_4f61bI0jKe_HFy0......4YnWnwFs<br>地址是:::https://mmbiz.qlogo.cn/mmbiz/oXGwXicXmia5XySWuNbR......cA3FSvzicc9Fw8EictQ2kbTvWlkLIqVlfLiaTJ8v1EVPQicS25Dw/0?wx_fmt=png2016-05-1318:16:20