C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件)

C#开发微信公众号之消息自动回复 作为计算机学院的学生的学生,时刻在打计算机学院官网的主意,前段时间我的一个好基友在我面前炫耀他的能够查课表的公众号(服务模拟登录返回数据),把我眼红得,所以我暗自下决心,自己一定要弄个微信公众号来玩玩儿。经过各种网上查资料,各种走弯路,还是实现了微信公众号机器人聊天功能。虽然这个很简单,但是网上完善而又详细的资料很难找,而且官网的开发文档只针对php语言发布了Demo,开发者文档简直坑爹,不过我还是 阅读详情

转自http://www.2cto.com/kf/201501/368937.html

第四,第五章已经讲了怎么处理用户发送的消息,本章就来讲讲怎么响应用户的请求。想必新手看到这个标题也就懵了,千万别懵,微信的接口就这样,在回复图片、音乐、语音等都需要将我们的媒体文件上传到微信的服务器才能使用。不知道这样的做法是出于什么考虑的,而且同是给用户回复消息,客服接口和群发接口发送的消息体格式竟然是不同的。估计是这几处接口不是同一个人写的,没有做好代码的统一,咱们屌丝开发者只能无力吐槽了。

 
在讲上传 下载接口前,需要先将下先来讲讲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可在微信公众平台官网-开发者中心页中获得(需要已经成为开发者,且帐号没有异常状态)。如下图:
 
image
 
获取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
 
 
/// <summary>
        /// 获取access token
        /// </summary>
        /// <param name="appid">第三方用户唯一凭证</param>
        /// <param name="secret">第三方用户唯一凭证密钥,即appsecret</param>
        /// <returns>AccessToken对象,expirestime是过期时间</returns>
        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<string>("access_token");
                    int expirestime = obj.Value<int>("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天后自动删除,以节省服务器资源。
 
上传多媒体的接口地址是:
 
http://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
    {
        /// <summary>
        /// 图片(image): 1M,支持JPG格式
        /// </summary>
        image,
        /// <summary>
        /// 语音(voice):2M,播放长度不超过60s,支持AMR\MP3格式
        /// </summary>
        voice,
        /// <summary>
        /// 视频(video):10MB,支持MP4格式
        /// </summary>
        video,
        /// <summary>
        /// 缩略图(thumb):64KB,支持JPG格式
        /// </summary>
        thumb
    }
 
然后定义返回值的类型:
 
 
public class UpLoadInfo
    {
        /// <summary>
        /// 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb,主要用于视频与音乐格式的缩略图)
        /// </summary>
        public string type { get; set; }
        /// <summary>
        /// 媒体文件上传后,获取时的唯一标识
        /// </summary>
        public string media_id { get; set; }
        /// <summary>
        /// 媒体文件上传时间戳
        /// </summary>
        public string created_at { get; set; }
    }
 
最后使用WebClient类来上传文件,并读出返回值,代码如下:
 
 
/// <summary>
        /// 微信上传多媒体文件
        /// </summary>
        /// <param name="filepath">文件绝对路径</param>
        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<UpLoadInfo>(retdata);
                }
                else
                {//否则,写错误日志
 
                    WriteBug(retdata);//写错误日志
                    return null;
                }
            }
        }
 
至此,在讲回复消息之前,插入了两个基础支持接口,由于各位整理归纳能力太烂了,各位看官请多包涵,如有问题就留言和我交流。 下面正式开始讲回复消息。在看下面内容的时候,请大家结合第四,第五章进行 阅读。
 
前面两章讲述了接收并处理用户发送的消息,讲到了一个消息基类BaseMessage,而不管我们接收到什么类型的消息,都需要可以调用方法,进行响应用户的请求,所以,用户回复用户请求的方法需要封装到基类中。下面先简单了解下公众号可以回复的消息类型,以及消息格式。
 
注意:
 
一旦遇到以下情况,微信都会在公众号会话中,向用户下发 系统提示“该公众号暂时无法提供服务,请稍后再试”:
 
1、开发者在5秒内未回复任何内容
2、开发者回复了异常数据,比如JSON数据等
回复文本消息
 
<xml>
<ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName>
<FromUserName><![CDATA[开发者 微信号]]></FromUserName>
<CreateTime>消息创建时间 (整型)</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Content><![CDATA[回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)]]></Content>
</xml>
 
回复图片消息
 
<xml>
<ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName>
<FromUserName><![CDATA[开发者微信号]]></FromUserName>
<CreateTime>消息创建时间 (整型)</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[通过上传多媒体文件,得到的id。]]></MediaId>
</Image>
</xml>
 
回复语音消息
 
<xml>
<ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName>
<FromUserName><![CDATA[开发者微信号]]></FromUserName>
<CreateTime>消息创建时间 (整型)</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<Voice>
<MediaId><![CDATA[通过上传多媒体文件,得到的id。]]></MediaId>
</Voice>
</xml>
 
回复视频消息
 
<xml>
<ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName>
<FromUserName><![CDATA[开发者微信号]]></FromUserName>
<CreateTime>消息创建时间 (整型)</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
<Video>
<MediaId><![CDATA[通过上传多媒体文件,得到的id。]]></MediaId>
<Title><![CDATA[视频消息的标题]]></Title> 
<Description><![CDATA[视频消息的描述]]></Description> 
</Video>
</xml>
 
回复音乐消息
 
<xml>
<ToUserName><![CDATA[接收方帐号(收到的OpenID)]]></ToUserName>
<FromUserName><![CDATA[开发者微信号]]></FromUserName>
<CreateTime>消息创建时间 (整型)</CreateTime>
<MsgType><![CDATA[music]]></MsgType>
<Music>
<ThumbMediaId><![CDATA[缩略图的媒体id,通过上传多媒体文件,得到的id。]]></ThumbMediaId>
<Title><![CDATA[视频消息的标题]]></Title> 
<Description><![CDATA[视频消息的描述]]></Description> 
<MusicURL><![CDATA[音乐链接]]></MusicURL> 
<HQMusicUrl><![CDATA[高质量音乐链接,WIFI环境优先使用该链接播放音乐]]></HQMusicUrl> 
</Music>
</xml>
 
回复图文消息
 
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<ArticleCount>2</ArticleCount>
<Articles>
<item>
<Title><![CDATA[title1]]></Title> 
<Description><![CDATA[description1]]></Description>
<PicUrl><![CDATA[picurl]]></PicUrl>
<Url><![CDATA[url]]></Url>
</item>
<item>
<Title><![CDATA[title]]></Title>
<Description><![CDATA[description]]></Description>
<PicUrl><![CDATA[picurl]]></PicUrl>
<Url><![CDATA[url]]></Url>
</item>
</Articles>
</xml>
 
回复图文中,item是一个项,一个item代码一个图文。在响应的时候,我们只需根据数据格式,替换掉对应的属性,然后Response.Write(s)即可。结合前两章的讲解,BaseMessage的最终代码如下:
 
 
/// <summary>
    /// 消息体基类
    /// </summary>
    public abstract class BaseMessage
    {
        /// <summary>
        /// 开发者微信号
        /// </summary>
        public string ToUserName { get; set; }
       /// <summary>
        /// 发送方帐号(一个OpenID)
       /// </summary>
        public string FromUserName { get; set; }
        /// <summary>
        /// 消息创建时间 (整型)
        /// </summary>
        public string CreateTime { get; set; }
        /// <summary>
        /// 消息类型
        /// </summary>
        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("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime>", FromUserName, ToUserName, Utils.ConvertDateTimeInt(DateTime.Now)));
            resxml.AppendFormat("<MsgType><![CDATA[text]]></MsgType><Content><![CDATA[{0}]]></Content><FuncFlag>0</FuncFlag></xml>", content);
            Response(param, resxml.ToString());
        }
        /// <summary>
        /// 回复消息(音乐)
        /// </summary>
        public  void ResMusic(EnterParam param, Music mu)
        {
            StringBuilder resxml = new StringBuilder(string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime>",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now)));
            resxml.Append(" <MsgType><![CDATA[music]]></MsgType>");
            resxml.AppendFormat("<Music><Title><![CDATA[{0}]]></Title><Description><![CDATA[{1}]]></Description>", mu.Title, mu.Description);
            resxml.AppendFormat("<MusicUrl><![CDATA[http://{0}{1}]]></MusicUrl><HQMusicUrl><![CDATA[http://{2}{3}]]></HQMusicUrl></Music><FuncFlag>0</FuncFlag></xml>", 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("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime>",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now)));
            resxml.Append(" <MsgType><![CDATA[video]]></MsgType>");
            resxml.AppendFormat("<Video><MediaId><![CDATA[{0}]]></MediaId>", v.media_id);
            resxml.AppendFormat("<Title><![CDATA[{0}]]></Title>", v.title);
            resxml.AppendFormat("<Description><![CDATA[{0}]]></Description></Video></xml>", v.description);
            Response(param, resxml.ToString());
        }
 
        /// <summary>
        /// 回复消息(图片)
        /// </summary>
        public  void ResPicture(EnterParam param, Picture pic, string domain)
        {
            StringBuilder resxml = new StringBuilder(string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime>",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now)));
            resxml.Append(" <MsgType><![CDATA[image]]></MsgType>");
            resxml.AppendFormat("<PicUrl><![CDATA[{0}]]></PicUrl></xml>", domain + pic.PictureUrl);
            Response(param, resxml.ToString());
        }
 
        /// <summary>
        /// 回复消息(图文列表)
        /// </summary>
        /// <param name="param"></param>
        /// <param name="art"></param>
        public  void ResArticles(EnterParam param, List<Articles> art)
        {
            StringBuilder resxml = new StringBuilder(string.Format("<xml><ToUserName><![CDATA[{0}]]></ToUserName><FromUserName><![CDATA[{1}]]></FromUserName><CreateTime>{2}</CreateTime>",FromUserName,ToUserName, Utils.ConvertDateTimeInt(DateTime.Now)));
            resxml.AppendFormat("<MsgType><![CDATA[news]]></MsgType><ArticleCount>{0}</ArticleCount><Articles>", art.Count);
            for (int i = 0; i < art.Count; i++)
            {
                resxml.AppendFormat("<item><Title><![CDATA[{0}]]></Title>  <Description><![CDATA[{1}]]></Description>", art[i].Title, art[i].Description);
                resxml.AppendFormat("<PicUrl><![CDATA[{0}]]></PicUrl><Url><![CDATA[{1}]]></Url></item>", 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("</Articles><FuncFlag>0</FuncFlag></xml>");
            Response(param, resxml.ToString());
        }
        /// <summary>
        /// 多客服转发
        /// </summary>
        /// <param name="param"></param>
        public  void ResDKF(EnterParam param)
        {
            StringBuilder resxml = new StringBuilder();
            resxml.AppendFormat("<xml><ToUserName><![CDATA[{0}]]></ToUserName>",FromUserName);
            resxml.AppendFormat("<FromUserName><![CDATA[{0}]]></FromUserName><CreateTime>{1}</CreateTime>",ToUserName,CreateTime);
            resxml.AppendFormat("<MsgType><![CDATA[transfer_customer_service]]></MsgType></xml>");
            Response(param, resxml.ToString());
        }
        /// <summary>
        /// 多客服转发如果指定的客服没有接入能力(不在线、没有开启自动接入或者自动接入已满),该用户会一直等待指定客服有接入能力后才会被接入,而不会被其他客服接待。建议在指定客服时,先查询客服的接入能力指定到有能力接入的客服,保证客户能够及时得到服务。
        /// </summary>
        /// <param name="param">用户发送的消息体</param>
        /// <param name="KfAccount">多客服账号</param>
        public  void ResDKF(EnterParam param, string KfAccount)
        {
            StringBuilder resxml = new StringBuilder();
            resxml.AppendFormat("<xml><ToUserName><![CDATA[{0}]]></ToUserName>",FromUserName);
            resxml.AppendFormat("<FromUserName><![CDATA[{0}]]></FromUserName><CreateTime>{1}</CreateTime>",ToUserName,CreateTime);
            resxml.AppendFormat("<MsgType><![CDATA[transfer_customer_service]]></MsgType><TransInfo><KfAccount>{0}</KfAccount></TransInfo></xml>", 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 属性
        /// <summary>
        /// 音乐链接
        /// </summary>
        public string MusicUrl { get; set; }
        /// <summary>
        /// 高质量音乐链接,WIFI环境优先使用该链接播放音乐
        /// </summary>
        public string HQMusicUrl { get; set; }
        /// <summary>
        /// 标题
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 描述
        /// </summary>
        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<Articles> art)中的Articles定义如下:
 
 
public class Articles
    {
        #region 属性
        /// <summary>
        /// 图文消息标题
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 图文消息描述
        /// </summary>
        public string Description { get; set; }
        /// <summary>
        /// 图片链接,支持JPG、PNG格式,较好的效果为大图640*320,小图80*80。
        /// </summary>
        public string PicUrl { get; set; }
        /// <summary>
        /// 点击图文消息跳转链接
        /// </summary>
        public string Url { get; set; }
        #endregion
    }
微信公众平台接收(回复)消息C#版 此代码仅包含接收消息(事件)、发送被动响应消息 C#版,类库基于framework4.0,但是除了T4模板,其他代码可直接用于2.0. 立即下载

相关推荐

微信公众号接口demo

此文档包含了c#与微信开发接口对接的所有代码,适合需要开发微信公共号接口的开发人员

C#微信公众号开发之微信消息回复及事件类型(四)

一、相关实体类 依据接收到的xml消息模板来创建对应的实体类,相关xml消息我就不在这里写了,可以去官方文档中查看https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140453 1.用户发送的xml消息通用节点 using System; using System.Collections.Generic; us...

ZhangY1217的博客 1928

C#Webservice+微信小程序上传多个文件

经过一上午的网上查找,实现的C#写的,Webservice接收微信小程序上传的图片文件,有单个图片的上传代码,也有多个图片的上传代码,包括网页木马验证等程序

微信公众平台-第三方平台开发(四)被动回复消息

这个问题卡了我两天的时间,一直没有头绪,文档都快翻烂了,还是没有解决,最后直接调用的客服发送消息的接口回复的。(有可能是因为natapp网速的原因,导致的回复超时,毕竟免费的内网穿透总会有它的缺点,的确是很慢)话不多说,直接上代码。

何时林听@ 1947

新版微信amr语音文件解密

新版微信(如微信6.2)在SD卡保存的语音文件表面上是amr后缀,实际上并不是amr文件,而是加密过的,无法直接导出在电脑中播放,本程序可以解密语音文件生成通用的mp3格式文件。

ASP.NET 下载微信录音AMR文件,使用FFmpeg实现AMR转换MP3示例源码

ASP.NET 下载微信录音AMR文件,使用FFmpeg实现AMR转换MP3示例源码

微信公众号被动消息回复实现

其实消息回复并不是特别难的,主要是能看懂文档就很容易就实现,但是微信文档有点抽象(其实是我菜)不好看懂,所以还是需要自己多尝试一下;传送门。

YXXXYX的博客 2443

Accelstepper 库中的参数计算公式

要完全调试电机的各个参数,例如最大速度,加速度等,就需要了解其计算公式和原理。 以下是代码注释: /// This code uses speed calculations as described in /// "Generate stepper-motor speed profiles in real time" by David Austin/// http://fab.cba.mi...

wenguitao的博客 4455

公众号接收普通消息并回复

涉及官方文档的两个知识点:接受普通消息、被动回复用户消息。希望实现的效果是公众号中用户发送什么就直接回复什么,但是有个类型不同意,所以做了调整 - 接收文字:原样回复文字 - 接收图片:原样回复图片 - 接收语音:原样回复语音 - 接收视频:回复已经上传好的视频(原样回复视频有坑) - 接收地理位置:回复mp3音乐(音乐文件有坑) - 接收链接:回复图文消息

洛塔博士的博客 734

从亚稳态到稳定传输:深入解析CDC跨时钟域同步的核心技术与设计实践

本文深入解析了CDC(跨时钟域同步)技术的核心问题与解决方案,重点探讨了亚稳态现象及其危害,详细介绍了同步器设计、MTBF计算方法以及单bit和多bit信号同步的实战技巧。通过Verilog代码示例和工程实践案例,帮助读者掌握从亚稳态到稳定传输的关键技术,提升数字电路设计的可靠性。

weixin_32822843的博客 246

特征提取神操作,登上Nature!计算速度狂提300%!

登上Nature!作者提出CVOCA,一种能同时处理数据的幅度和相位信息的卷积模型,在性能远超SOTA的同时,计算速度更是狂飙300%!实际上,作为机器学习和深度学习的核心技术,特征提取一直都是研究的热门!它直接影响着模型的准确性、计算效率、可解释性……同时,它也是我们改模型涨点,最好操作的部分!因为可切入点的真的非常之丰富,不管是轻量化、多尺度、时域与频域结合等,都能使模型性能得到提升!

2401_82426425的博客 4036

C#微信公众号开发系列教程四(接收普通消息)

微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C#微信公众号开发系列教程四(接收普通消息) C#微信公众号开发系列教程五(接收事件推送与消息排重) C#微信公众号开发系列教程六(被动回复与上传下载多媒体文件) 微信中的消息类型有:文...

weixin_30386713的博客 380

FPGA—DHT11数字温湿度传感器

1. DH1T11温湿度传感器与DS18B20温湿度传感器非常类似,都是严格按照时序要求写代码。建议可以比较学习。2. 显示温度与湿度部分的数据处理,采用 X10 进行在数码管上的移一位显示,配合了数码管小数部分的显示特点又区分了温度与湿度。3. 程序是按照一个接一个状态及顺序跳转的,建议使用状态机。说明:本人使用的是野火家Xilinx Spartan6系列开发板及配套教程,以上内容如有疑惑或错误欢迎评论区指出,或者移步B站观看野火家视频教程。

m0_72885897的博客 4779

微信公众号被动回复

case 'text': $template = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]>&lt...

joker6295的博客 530

Revit获取族预览图

最近做到和族库相关的功能需要获取到族文件的预览图,在RevitAPI中提供了ElementType.GetPreviewImage方法,但是前提就是你是在Revit里面操作的,并且已经拿到了Symbol对象实例,才可以调用此方法。然后在网上找了另外一种方式,通过读取Revit文件,在REVITPREVIEW4.0字段截取文件信息,将其转换为图片格式。 一、使用RevitAPI中ElementType.GetPreviewImage方法 [Autodesk.Revit.Attributes.Transac.

weixin_44631419的博客 1753

SAP 系统和银行系统通过 SM2 加密算法进行集成

SM2 是基于椭圆曲线离散对数问题(ECDLP)的一种公钥密码算法。椭圆曲线加密的核心原理,是利用了一个数学难题:在椭圆曲线群上,已知曲线上两点的运算结果,逆向推导出这两个点的具体信息是非常困难的。这样的复杂度使得基于椭圆曲线的密码体制比传统的 RSA 更加难以破解。在 SM2 加密中,公钥和私钥的生成与传统的椭圆曲线加密类似。选择一个椭圆曲线和一个基点 P。使用私钥 d,计算公钥 P’ = d * P。私钥 d 保密,而公钥 P’ 可公开分发,用于加密数据。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1211

微信公众号开发(二)被动回复文本消息

微信公众号开发(二)被动回复文本消息 如题,接上篇公众号配置成功以后,首先想到的是处理用户扫码,关键字回复,关注、取关等事件的捕获,本文主要是关键字回复文本消息的实现。 先说思路:用户给公众号发送文本消息后,微信会给配置的url发送post请求,里面包含了发送人的一些信息,数据包如下: <xml> <ToUserName><![CDATA[toUser]]></ToUserName> <FromUserName><![CDAT

醉酒的李白、的博客 1536

FineBI学习总结

交叉表:一组作为行标题显示在表的左部,另一组作为列标题显示在表的顶部。连接到数据,如果数据不满足数据分析的需求,先进行自助数据集处理。数据集分类:DB表、SQL、Excel、自助数据集。分组表:将报表中的数据按相同项合并为一组显示。1、数据准备2、制作仪表板3、分享仪表板。左合并:保留左边全部数据,合并右边。右合并:保留右边全部数据,合并左边。上下拼接:上下拼接到一张表数据。3、如何实现拼表:多表拼一张。分组–业务包–数据集–字段。字段分类:数值、文本和日期。目录–仪表板–数据准备。维度:文本和日期类型。

Rsun2018的博客 1561

微信公众号开发之自动消息回复

微信公众号后台有编辑模式和代码模式两种,设置成代码模式后,微信服务器会把公众号收到的所有消息以post方式发送到验证接入填写的url上,携带的请求参数为xml格式,由自己写的controller负责处理消息并按照微信要求的发送给微信服务器。Controller通过请求方式来分别处理验证接入和消息处理。 微信消息分为文本消息、语音消息、位置消息等多种格式,我做的是文本消息。文本消息的xml格式如下...

RobotBing的博客 1479

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

微信公众号开发之回复图文消息(被动)

目录 (一)微信公众号开发之VS远程调试 (二)微信公众号开发之基础梳理 (三)微信公众号开发之自动消息回复和自定义菜单 (四)微信公众号开发之网页授权获取用户基本信息 (五)微信公众号开发之网页中及时获取当前用户Openid及注意事项 (六)微信公众号开发之扫码支付 (七)微信公众号开发之公众号支付 (八)微信公众号开发之现金红包 (九)微信公众号开发之回复图文消息(...

weixin_30565199的博客 811

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

微信开发之事件推送与被动回复

直接上代码,公众号后台基本配置:设置URL、token、EncodingAESKey,并退出启用改配置,后上代码class TestController extends Controller { //公众号后台的URL的接口 public function index() { //将timestamp,nonce,token按字典序排序 $timesta

zhenglouji9184的博客 1468

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

上一篇: 微信公众平台开发上传下载多媒体文件
下一篇: js图片上传预览
killcwd
博客等级 码龄16年 49粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值