不解释了,会一点微信开发,分析下代码就会了
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;
}
}
}