千家信息网

微信开发之如何实现被动回复和上传下载文件

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,小编给大家分享一下微信开发之如何实现被动回复和上传下载文件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!在讲上传下载接口前
千家信息网最后更新 2026年11月01日微信开发之如何实现被动回复和上传下载文件

小编给大家分享一下微信开发之如何实现被动回复和上传下载文件,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

在讲上传下载接口前,需要先将下先来讲讲access_token获取方法。在微信接口开发的过程access_token是至关重要的,是公众号的全局唯一票据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。需要注意的时,一个公众号同时只存在一个有效的access_token,开发者需要在access_token过期前,刷新access_token。在刷新的过程中,公众平台后台会保证在刷新短时间内,新老access_token都可用,这保证了第三方业务的平滑过渡。

公众号可以使用AppID和AppSecret调用本接口来获取access_token。AppID和AppSecret可在微信公众平台官网-开发者中心页中获得(需要已经成为开发者,且帐号没有异常状态)。如下图:

获取access_token的接口地址是:

https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
将appid和secret替换成你自己的。

发送get请求到这个地址,返回的数据如下:

{"access_token":"eEd6dhp0s24JfWwDyGBbrvJxnhqHTSYZ8MKdQ7MuCGBKxAjHv-tEIwhFZzn102lGvIWxnjZZreT6C1NCT9fpS7NREOkEX42yojVnqKVaicg","expires_in":7200}
我们只需解析这个json,即可获取到我们所需的access_token.代码如下:
AccessToken实体类:
public class AccessToken    {        public string token { get; set; }        public DateTime expirestime { get; set; }    }

获取access token

///         /// 获取access token        ///         /// 第三方用户唯一凭证        /// 第三方用户唯一凭证密钥,即appsecret        /// AccessToken对象,expirestime是过期时间        public static AccessToken GetAccessToken(string appid, string secret)        {            try            {                string url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appid, secret);                string retdata = Utils.HttpGet(url);                if (retdata.Contains("access_token"))                {                    JObject obj = (JObject)JsonConvert.DeserializeObject(retdata);                    string token = obj.Value("access_token");                    int expirestime = obj.Value("expires_in");                    return new AccessToken { token = token, expirestime = DateTime.Now.AddSeconds(expirestime) };                }                else                {                    WriteBug(retdata);//写错误日志                }                return null;            }            catch (Exception e)            {                WriteBug(e.ToString());//写错误日志                return null;            }        }

access_token获取成功后,下面来讲上传下载多媒体文件吧。官方说,公众号在使用接口时,对多媒体文件、多媒体消息的获取和调用等操作,是通过media_id来进行的(咱读书少,不明白为什么不能使用url,而要多此一举先上传到服务器在发送)。通过本接口,公众号可以上传或下载多媒体文件。但请注意,每个多媒体文件(media_id)会在上传、用户发送到微信服务器3天后自动删除,以节省服务器资源。

上传多媒体的接口地址是:

file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE

其中access_token为调用接口凭证,type是媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb)

注意事项:

上传的多媒体文件有格式和大小限制,如下:

  • 图片(image): 1M,支持JPG格式

  • 语音(voice):2M,播放长度不超过60s,支持AMR\MP3格式

  • 视频(video):10MB,支持MP4格式

  • 缩略图(thumb):64KB,支持JPG格式

媒体文件在后台保存时间为3天,即3天后media_id失效。

为了方便调用,将媒体文件的类型定义为枚举,代码如下:

public enum MediaType    {        ///         /// 图片(image): 1M,支持JPG格式        ///         image,        ///         /// 语音(voice):2M,播放长度不超过60s,支持AMR\MP3格式        ///         voice,        ///         /// 视频(video):10MB,支持MP4格式        ///         video,        ///         /// 缩略图(thumb):64KB,支持JPG格式        ///         thumb    }

然后定义返回值的类型:

public class UpLoadInfo    {        ///         /// 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb,主要用于视频与音乐格式的缩略图)        ///         public string type { get; set; }        ///         /// 媒体文件上传后,获取时的唯一标识        ///         public string media_id { get; set; }        ///         /// 媒体文件上传时间戳        ///         public string created_at { get; set; }    }

最后使用WebClient类来上传文件,并读出返回值,代码如下:

///         /// 微信上传多媒体文件        ///         /// 文件绝对路径        public static ReceiveModel.UpLoadInfo WxUpLoad(string filepath, string token, MediaType mt)        {            using (WebClient client = new WebClient())            {                byte[] b = client.UploadFile(string.Format("http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={0}&type={1}", token, mt.ToString()), filepath);//调用接口上传文件                string retdata = Encoding.Default.GetString(b);//获取返回值                if (retdata.Contains("media_id"))//判断返回值是否包含media_id,包含则说明上传成功,然后将返回的json字符串转换成json                {                    return JsonConvert.DeserializeObject(retdata);                }                else                {//否则,写错误日志                    WriteBug(retdata);//写错误日志                    return null;                }            }        }

至此,在讲回复消息之前,插入了两个基础支持接口,由于各位整理归纳能力太烂了,各位看官请多包涵,如有问题就留言和我交流。 下面正式开始讲回复消息。在看下面内容的时候,请大家结合第四,第五章进行阅读。

前面两章讲述了接收并处理用户发送的消息,讲到了一个消息基类BaseMessage,而不管我们接收到什么类型的消息,都需要可以调用方法,进行响应用户的请求,所以,用户回复用户请求的方法需要封装到基类中。下面先简单了解下公众号可以回复的消息类型,以及消息格式。

注意:

一旦遇到以下情况,微信都会在公众号会话中,向用户下发系统提示"该公众号暂时无法提供服务,请稍后再试":

1、开发者在5秒内未回复任何内容2、开发者回复了异常数据,比如JSON数据等
回复文本消息
消息创建时间 (整型)
回复图片消息
消息创建时间 (整型)
回复语音消息
消息创建时间 (整型)
回复视频消息
消息创建时间 (整型)
回复音乐消息
消息创建时间 (整型)<![CDATA[视频消息的标题]]>
回复图文消息
123456782<![CDATA[title1]]> <![CDATA[title]]>

回复图文中,item是一个项,一个item代码一个图文。在响应的时候,我们只需根据数据格式,替换掉对应的属性,然后Response.Write(s)即可。结合前两章的讲解,BaseMessage的最终代码如下:

///     /// 消息体基类    ///     public abstract class BaseMessage    {        ///         /// 开发者微信号        ///         public string ToUserName { get; set; }       ///         /// 发送方帐号(一个OpenID)       ///         public string FromUserName { get; set; }        ///         /// 消息创建时间 (整型)        ///         public string CreateTime { get; set; }        ///         /// 消息类型        ///         public MsgType MsgType { get; set; }        public virtual void ResponseNull()        {            Utils.ResponseWrite("");        }        public virtual void ResText(EnterParam param, string content)        {            StringBuilder resxml = new StringBuilder(string.Format("{2}", FromUserName, ToUserName, Utils.ConvertDateTimeInt(DateTime.Now)));            resxml.AppendFormat("0", content);            Response(param, resxml.ToString());        }        ///         /// 回复消息(音乐)        ///         public  void ResMusic(EnterParam param, Music mu)        {            StringBuilder resxml = new StringBuilder(string.Format("{2}",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now)));            resxml.Append(" ");            resxml.AppendFormat("<![CDATA[{0}]]>", mu.Title, mu.Description);            resxml.AppendFormat("0", VqiRequest.GetCurrentFullHost(), mu.MusicUrl, VqiRequest.GetCurrentFullHost(), mu.HQMusicUrl);            Response(param, resxml.ToString());        }        public  void ResVideo(EnterParam param, Video v)        {            StringBuilder resxml = new StringBuilder(string.Format("{2}",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now)));            resxml.Append(" ");            resxml.AppendFormat("", v.description);            Response(param, resxml.ToString());        }        ///         /// 回复消息(图片)        ///         public  void ResPicture(EnterParam param, Picture pic, string domain)        {            StringBuilder resxml = new StringBuilder(string.Format("{2}",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now)));            resxml.Append(" ");            resxml.AppendFormat("", domain + pic.PictureUrl);            Response(param, resxml.ToString());        }        ///         /// 回复消息(图文列表)        ///         ///         ///         public  void ResArticles(EnterParam param, List art)        {            StringBuilder resxml = new StringBuilder(string.Format("{2}",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now)));            resxml.AppendFormat("{0}", art.Count);            for (int i = 0; i < art.Count; i++)            {                resxml.AppendFormat("<![CDATA[{0}]]>  ", art[i].Title, art[i].Description);                resxml.AppendFormat("", art[i].PicUrl.Contains("http://") ? art[i].PicUrl : "http://" + VqiRequest.GetCurrentFullHost() + art[i].PicUrl, art[i].Url.Contains("http://") ? art[i].Url : "http://" + VqiRequest.GetCurrentFullHost() + art[i].Url);            }            resxml.Append("0");            Response(param, resxml.ToString());        }        ///         /// 多客服转发        ///         ///         public  void ResDKF(EnterParam param)        {            StringBuilder resxml = new StringBuilder();            resxml.AppendFormat("",FromUserName);            resxml.AppendFormat("{1}",ToUserName,CreateTime);            resxml.AppendFormat("");            Response(param, resxml.ToString());        }        ///         /// 多客服转发如果指定的客服没有接入能力(不在线、没有开启自动接入或者自动接入已满),该用户会一直等待指定客服有接入能力后才会被接入,而不会被其他客服接待。建议在指定客服时,先查询客服的接入能力指定到有能力接入的客服,保证客户能够及时得到服务。        ///         /// 用户发送的消息体        /// 多客服账号        public  void ResDKF(EnterParam param, string KfAccount)        {            StringBuilder resxml = new StringBuilder();            resxml.AppendFormat("",FromUserName);            resxml.AppendFormat("{1}",ToUserName,CreateTime);            resxml.AppendFormat("{0}", KfAccount);            Response(param, resxml.ToString());        }        private  void Response(EnterParam param, string data)        {            if (param.IsAes)            {                var wxcpt = new MsgCrypt(param.token, param.EncodingAESKey, param.appid);                wxcpt.EncryptMsg(data, Utils.ConvertDateTimeInt(DateTime.Now).ToString(), Utils.GetRamCode(), ref data);            }            Utils.ResponseWrite(data);        }    }

上面的代码中,public void ResDKF(EnterParam param),public void ResDKF(EnterParam param, string KfAccount)两个方法时多客服中,用户转发用户发送的消息的,多客服将在后期的博文中进行更新,敬请期待。

public void ResMusic(EnterParam param, Music mu)方法中的Music类的定义如下:

public class Music    {        #region 属性        ///         /// 音乐链接        ///         public string MusicUrl { get; set; }        ///         /// 高质量音乐链接,WIFI环境优先使用该链接播放音乐        ///         public string HQMusicUrl { get; set; }        ///         /// 标题        ///         public string Title { get; set; }        ///         /// 描述        ///         public string Description { get; set; }        #endregion    }

public void ResVideo(EnterParam param, Video v)方法中的Video类的定义如下:

public class Video    {        public string title { get; set; }        public string media_id { get; set; }        public string description { get; set; }    }

public void ResArticles(EnterParam param, List art)中的Articles定义如下:

public class Articles    {        #region 属性        ///         /// 图文消息标题        ///         public string Title { get; set; }        ///         /// 图文消息描述        ///         public string Description { get; set; }        ///         /// 图片链接,支持JPG、PNG格式,较好的效果为大图640*320,小图80*80。        ///         public string PicUrl { get; set; }        ///         /// 点击图文消息跳转链接        ///         public string Url { get; set; }        #endregion    }

以上是"微信开发之如何实现被动回复和上传下载文件"这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注行业资讯频道!

消息 文件 格式 用户 公众 接口 开发 时间 支持 多媒体 图文 开发者 类型 接入 代码 媒体 媒体文件 方法 视频 音乐 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网科技的 万达互联网科技 天下捷融互联网科技 互联网科技公司介绍 广西拼得多互联网科技有限公司 哈尔滨秒房互联网科技有限公司 互联网汽车科技小镇 隆华科技工业互联网 济南华为互联网科技产业总部基地 中国的互联网科技企业的崛起 世界互联网科技公司市值排名 苏州铭阳互联网科技有限公司 速维有品互联网信息科技(苏州)有限公司 米聚互联网科技南京有限公司排面 互联网科技大赛获奖感言 徐州市互联网科技有限公司 福仕德教育科技互联网 长沙易易互联网科技有限公司 前海云享互联网科技 广州全民伙伴互联网科技有限公司 咖啡 深圳互联网络科技有限公司 互联网科技ppt模板 互联网巨头投资的硬核科技 科技与互联网的利与弊 小米互联网科技园设置 中国科技创新与世界互联网大会 华中科技大学互联网的牛人 互联网科技实习生岗位 安徽零酒互联网科技有限公司
0