不解释了,会一点微信开发,分析下代码就会了
using Abp.Authorization; using Microsoft.AspNetCore.Mvc; using MkGzhh.Authorization; using MkGzhh.Wechat.Dto; using MkGzhh.Wechat.ReturnDto; using MkGzhh.Wechat.WechatMessages; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Security; using System.Text; using System.Text.RegularExpressions; using System.Threading.Tasks; namespace MkGzhh.Wechat { /// <summary> /// 微信素材管理 /// </summary> [AbpAuthorize(PermissionNames.weChatmaterial)] public class WechatMaterialService : MkGzhhAppServiceBase, IWechatMaterialService { public string urlname { get; set; } /// <summary> /// http协议 /// </summary> HttpClient httpClient = new HttpClient(); private readonly IWechatUserTagService _wechatUserTagService; /// <summary> /// 依赖注入 /// </summary> /// <param name="wechatUserTagService"></param> public WechatMaterialService(IWechatUserTagService wechatUserTagService) { _wechatUserTagService = wechatUserTagService; } /// <summary> /// 得到ACCESS_TOKEN /// </summary> /// <returns></returns> private async Task<string> GetACCESS_TOKEN() { var getParameter = await _wechatUserTagService.GetACCESS_TOKEN(); return getParameter; } /// <summary> /// 添加素材。临时素材的有效时间为3天 /// imgurl为 服务器文件的物理路径,可用Request.MapPath将虚拟路径转换为物理路径。也可为网络路径,如:http://XXXX /// </summary> /// <param name="imgurl"></param> /// <param name="urlname">文件的名字(如果不传就默认为地址的名字,当vue的文件上传控件会出错)</param> /// <param name="IsTemp">是否为临时素材 只有永久输出会在平台展示</param> /// <param name="videotitle">视频标题</param> /// <param name="mediaType">image 图片(image)格式语音(voice)视频(video):10MB,支持MP4格式缩略图(thumb):64KB,支持JPG格式,图文(news)</param> /// <param name="videointroduction">视频描述</param> /// <returns></returns> [HttpGet] public async Task<JObject> UpdateMaterial(string imgurl, string urlname, string mediaType, bool IsTemp, string videotitle = "", string videointroduction = "") { this.urlname = urlname; string url = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={0}&type={1}"; if (!IsTemp) { //永久素材接口 url = "http://api.weixin.qq.com/cgi-bin/material/add_material?access_token={0}&type={1}"; } //把内容存进表单 var formlist = new List<FormEntity> { new FormEntity {IsFile = true, Name = "media", Value = imgurl} }; //如果是视频类型就做特殊处理 if (mediaType == "video" && !IsTemp) { //新增视频素材的特殊处理 就是加 标题和描述2个参数列 var value = JsonConvert.SerializeObject(new { title = videotitle, introduction = videointroduction }); //加进数据表单 formlist.Add(new FormEntity { IsFile = false, Name = "description", Value = value }); } var accessToken = await GetACCESS_TOKEN(); string filename = imgurl; var set = PostResult(formlist, string.Format(url, accessToken, mediaType.ToString())); return set; } /// <summary> /// 获取临时素材的url /// </summary> /// <param name="mediaId">素材ID</param> /// <returns>url</returns> public async Task<string> GetTempUrlAsync(string mediaId) { string accessToken = await GetACCESS_TOKEN(); var url = "http://api.weixin.qq.com/cgi-bin/media/get?access_token={0}&media_id={1}"; var upload = string.Format(url, accessToken, mediaId); return upload; } /// <summary> /// 获取永久素材的url /// </summary> /// <param name="mediaId">素材ID</param> /// <param name="stream"></param> /// <returns>url</returns> public async Task<JObject> GetperpetualUrlAsync(mediaIdDto mediaId) { string accessToken = await GetACCESS_TOKEN(); var url = string.Format("https://api.weixin.qq.com/cgi-bin/material/get_material?access_token={0}", accessToken); //序列化为json var myContent = JsonConvert.SerializeObject(mediaId); var byteContent = new StringContent(myContent); var getParameter = await httpClient.PostAsync(url, byteContent); var retdata = await getParameter.Content.ReadAsStringAsync(); JObject jb = (JObject)JsonConvert.DeserializeObject(retdata); return jb; } public async Task<JObject> GetnewUrlAsync(mediaIdDto mediaId) { var access_token = await GetACCESS_TOKEN(); //序列化为json var myContent = JsonConvert.SerializeObject(mediaId); var byteContent = new StringContent(myContent); //发送 var getParameter = await httpClient.PostAsync("https://api.weixin.qq.com/cgi-bin/material/get_material?access_token=" + access_token, byteContent); //发送后返回的内容 var magess = await getParameter.Content.ReadAsStringAsync(); JObject jb = (JObject)JsonConvert.DeserializeObject(magess); return jb; } /// <summary> /// 新增永久图文素材 /// </summary> /// <param name="articles"></param> /// <returns></returns> public async Task<JObject> AddArticleAsync(Article2Dto articles) { var access_token = await GetACCESS_TOKEN(); //序列化为json var myContent = JsonConvert.SerializeObject(articles); var byteContent = new StringContent(myContent); //发送 var getParameter = await httpClient.PostAsync("https://api.weixin.qq.com/cgi-bin/material/add_news?access_token=" + access_token, byteContent); //发送后返回的内容 var magess = await getParameter.Content.ReadAsStringAsync(); JObject jb = (JObject)JsonConvert.DeserializeObject(magess); return jb; } /// <summary> /// 获取素材总数 /// </summary> /// <returns></returns> public async Task<JObject> GetAllMaterialCount() { var access_token = await GetACCESS_TOKEN(); var getParameter = await httpClient.GetStringAsync("https://api.weixin.qq.com/cgi-bin/material/get_materialcount?access_token=" + access_token); JObject jb = (JObject)JsonConvert.DeserializeObject(getParameter); return jb; } /// <summary> /// 获取素材列表 /// </summary> /// <param name="Magess"></param> /// <returns></returns> [HttpPost] public async Task<JObject> GetMaterialList(GetMaterialListDto Magess) { var access_token = await GetACCESS_TOKEN(); //序列化为json var myContent = JsonConvert.SerializeObject(Magess); var byteContent = new StringContent(myContent); //发送 var getParameter = await httpClient.PostAsync("https://api.weixin.qq.com/cgi-bin/material/batchget_material?access_token=" + access_token, byteContent); //发送后返回的内容 var magess = await getParameter.Content.ReadAsStringAsync(); JObject jb = (JObject)JsonConvert.DeserializeObject(magess); return jb; } /// <summary> /// 删除永久性素材 /// </summary> /// <param name="Magess">永久素材的ID</param> /// <returns></returns> public async Task<JObject> DelMaterial(DelMaterialDto Magess) { var access_token = await GetACCESS_TOKEN(); //序列化为json var myContent = JsonConvert.SerializeObject(Magess); var byteContent = new StringContent(myContent); //发送 var getParameter = await httpClient.PostAsync("https://api.weixin.qq.com/cgi-bin/material/del_material?access_token=" + access_token, byteContent); //发送后返回的内容 var magess = await getParameter.Content.ReadAsStringAsync(); JObject jb = (JObject)JsonConvert.DeserializeObject(magess); return jb; } //-------------------------------------------- /// <summary> /// 发起post请求,并获取请求返回值 /// </summary> /// <typeparam name="T">返回值类型</typeparam> /// <param name="formEntities"></param> /// <param name="url">接口地址</param> public JObject PostResult(List<FormEntity> formEntities, string url) { var retdata = HttpPostForm(url, formEntities); JObject jb = (JObject)JsonConvert.DeserializeObject(retdata); return jb; } /// <summary> /// 解析地址表单 /// </summary> /// <param name="url"></param> /// <param name="formEntities"></param> /// <returns></returns> public string HttpPostForm(string url, List<FormEntity> formEntities) { //分割字符串 var boundary = "----" + DateTime.Now.Ticks.ToString("x"); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((a, b, c, d) => true); request.ContentType = "multipart/form-data; boundary=" + boundary; MemoryStream stream = new MemoryStream(); #region 将非文件表单写入到内存流中 foreach (var entity in formEntities.Where(f => f.IsFile == false)) { var temp = new StringBuilder(); temp.AppendFormat("\r\n--{0}", boundary); temp.AppendFormat("\r\nContent-Disposition: form-data; name=\"{0}\"", entity.Name); temp.Append("\r\n\r\n"); temp.Append(entity.Value); byte[] b = Encoding.UTF8.GetBytes(temp.ToString()); stream.Write(b, 0, b.Length); } #endregion #region 将文件表单写入到内存流 foreach (var entity in formEntities.Where(f => f.IsFile == true)) { byte[] filedata = null; //+".jpg" var filename = Path.GetFileName(entity.Value); if (this.urlname != null) { filename = this.urlname; } //表示是网络资源 if (entity.Value.Contains("http")) { //处理网络文件 ,就是通过 DownloadData 这个方法把,连接的流数据读出来 using (var client = new WebClient()) { filedata = client.DownloadData(entity.Value); } } else { //处理物理路径文件 using (FileStream file = new FileStream(entity.Value, FileMode.Open, FileAccess.Read)) { filedata = new byte[file.Length]; file.Read(filedata, 0, (int)file.Length); } } var temp = string.Format("\r\n--{0}\r\nContent-Disposition: form-data; name=\"{1}\"; filename=\"{2}\"\r\n\r\n", boundary, entity.Name, filename); byte[] b = Encoding.UTF8.GetBytes(temp); stream.Write(b, 0, b.Length); stream.Write(filedata, 0, filedata.Length); } #endregion //结束标记 byte[] foot_data = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); stream.Write(foot_data, 0, foot_data.Length); Stream reqStream = request.GetRequestStream(); stream.Position = 0L; //将Form表单生成流写入到请求流中 stream.CopyTo(reqStream); stream.Close(); reqStream.Close(); using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { return reader.ReadToEnd();//获取响应 } } } /// <summary> /// HTTP POST请求URL。 /// </summary> /// <param name="url">请求的url</param> /// <param name="param">请求的参数</param> /// <param name="stream">如果响应的是文件,则此参数表示的是文件流</param> public static string HttpPost(string url, string param, out FileStreamInfo stream) { stream = null; //当请求为https时,验证服务器证书 ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback((a, b, c, d) => { return true; }); HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); request.Method = "POST"; request.ContentType = "application/x-www-form-urlencoded"; request.Accept = "*/*"; request.Timeout = 15000; request.AllowAutoRedirect = false; string responseStr = ""; using (StreamWriter requestStream = new StreamWriter(request.GetRequestStream())) { requestStream.Write(param);//将请求的数据写入到请求流中 } using (HttpWebResponse response = (HttpWebResponse)request.GetResponse()) { if (response.ContentType == "application/octet-stream")//如果响应的是文件流,则不将响应流转换成字符串 { stream = new FileStreamInfo(); response.GetResponseStream().CopyTo(stream); #region 获取响应的文件名 Regex reg = new Regex(@"(\w+)\.(\w+)"); var result = reg.Match(response.GetResponseHeader("Content-disposition")).Groups; stream.FileName = result[0].Value; #endregion responseStr = ""; } else { using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8)) { responseStr = reader.ReadToEnd();//获取响应 } } } return responseStr; } } }