上来就直接贴代码了,具体问题放到最后说,这个类我将方法全都封装在里面了,基本上拿去修改一下就可以用了
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using System.Web.SessionState;
using Website_CS;
using mgtArticle.mgtArticle;
using System.Net;
using System.Text;
using System.IO;
using System.Data;
using BHWeb;
namespace mgtArticle.wxArticle
{
//此类用于微信功能
public class WebChatHelper
{
private Regex _regex = new Regex(@"{.*}", RegexOptions.IgnoreCase);
#region 获取access_token
/// <summary>
/// 获取access_token
/// </summary>
/// <param name="redirect_uri">请求acess_token的地址</param>
/// <param name="appId">微信appID</param>
/// <param name="appSecret">微信appSecret</param>
/// <returns>access_token</returns>
public string GetAccessToken(string redirect_uri, string appId, string appSecret)
{
HttpHelper helper = new HttpHelper();
string access_token = "";
//获取access_token、openId
string access_Token_Url = string.Format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={0}&secret={1}", appId, appSecret);
string get_Token = helper.GetPageResponse_Get(access_Token_Url, redirect_uri, "*/*");
if (_regex.IsMatch(get_Token))
get_Token = _regex.Match(get_Token).Value;
var result = JsonConvert.DeserializeObject<Get_Access_token>(get_Token);
access_token = result.Access_Token;
return access_token;
}
/// <summary>
/// 上传文件
/// </summary>
/// <param name="access_token">微信返回的access_token</param>
/// <param name="type">上传文件的类型</param>
/// <param name="path"></param>
/// <returns></returns>
private static string UploadFile(string access_token, string type, string path)
{
// 设置参数
string url = string.Format("http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={0}&type={1}", access_token, type);
return HttpUploadFile(url, path);
}
private static string UploadImg(string access_token, string path)
{
// 设置参数
string url = string.Format("https://api.weixin.qq.com/cgi-bin/media/uploadimg?access_token={0}", access_token);
return HttpUploadFile(url, path);
}
/// <summary>
/// Http上传文件
/// </summary>
public static string HttpUploadFile(string url, string path)
{
// 设置参数
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = "POST";
string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;
byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("rn--" + boundary + "rn");
byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("rn--" + boundary + "--rn");
int pos = path.LastIndexOf("");
string fileName = path.Substring(pos + 1);
//请求头部信息
StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name="file";filename="{0}"rnContent-Type:application/octet-streamrnrn", fileName));
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString());
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read);
byte[] bArr = new byte[fs.Length];
fs.Read(bArr, 0, bArr.Length);
fs.Close();
Stream postStream = request.GetRequestStream();
postStream.Write(itemBoundaryBytes, 0, itemBoundaryBytes.Length);
postStream.Write(postHeaderBytes, 0, postHeaderBytes.Length);
postStream.Write(bArr, 0, bArr.Length);
postStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
postStream.Close();
//发送请求并获取相应回应数据
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才开始向目标网页发送Post请求
Stream instream = response.GetResponseStream();
StreamReader sr = new StreamReader(instream, Encoding.UTF8);
//返回结果网页(html)代码
string content = sr.ReadToEnd();
return content;
}
#endregion
#region 拼接图文内容
/// <summary>
/// 拼接图文消息素材Json字符串
/// </summary>
/// <param name="access_token">微信获取的access_token</param>
/// <param name="cIDs">文章的id,用于去数据库读取多个文章用,隔开</param>
/// <returns>拼接好的微信文章Json数据或错误内容,格式为1|Json数据或-1|错误内容</returns>
public string GetArticlesJsonStr(string access_token, string cIDs)
{
RecordSet RS = new RecordSet(BHSet.ConnString, SqlSelector.MSSql);
StringBuilder sbArticlesJson = new StringBuilder();
sbArticlesJson.Append("{"articles":[");//图文消息,一个图文消息支持1到10条图文
string[] arr_id = cIDs.Split(‘,‘);
for (int i = 0; i < arr_id.Length; i++)
{
string sql = "select * from Article where cID=‘" + arr_id[i] + "‘ and iStatus=‘1‘";
RS.Execute(sql);
if (RS.RecordCount > 0)
{
foreach (DataRow dr in RS.Rows)
{
string path = HttpContext.Current.Server.MapPath(getPicurte(dr["cContent"].ToString()));
if (!File.Exists(path))
{
return "-1|要发送的图片不存在";
}
// 上传图片返回媒体ID
string msg = UploadFile(access_token, "image", path);
if (_regex.IsMatch(msg))
msg = _regex.Match(msg).Value;
var result = JsonConvert.DeserializeObject<Get_Media_Id>(msg);
string thumb_media_id = result.Media_ID;
string noPicContent = GetNoPicarticle(dr["cContent"].ToString());//去除文章内容中的图片地址
if (noPicContent.Length > 54)
noPicContent = noPicContent.Substring(0, 53);
string changePicContent = GetReplacePic(dr["cContent"].ToString(),access_token);//替换文章内容中的图片地址
sbArticlesJson.Append("{");
sbArticlesJson.Append(""thumb_media_id":"" + thumb_media_id + "",");
sbArticlesJson.Append(""author":"律桥法律平台",");
sbArticlesJson.Append(""title":"" + dr["cTitle"].ToString() + "",");
sbArticlesJson.Append(""content_source_url":"http://www.lvqiao.net/Mobile/ArticleDetail.aspx?cID=" + dr["cID"].ToString() + "",");//在图文消息页面点击“阅读原文”后的页面
sbArticlesJson.Append(""content":"" + changePicContent + "",");//图文消息页面的内容,支持HTML标签。具备微信支付权限的公众号,可以使用a标签,其他公众号不能使用
sbArticlesJson.Append(""digest":"" + noPicContent + "",");//图文消息的描述
sbArticlesJson.Append(i == arr_id.Length - 1 ? ""show_cover_pic":"0"}" : ""show_cover_pic":"0"},");// 是否显示封面,1为显示,0为不显示
}
}
}
sbArticlesJson.Append("]}");
return "1|"+sbArticlesJson.ToString();
}
//获取文章内容中第一张的图片路径
private string getPicurte(string cContent)
{
string src = "";
int iIndex = 0;
int iEnd = 0;
try
{
iIndex = cContent.ToLower().IndexOf("src="");
if (iIndex > 0)
{
iIndex = cContent.ToLower().IndexOf(""", iIndex);
iEnd = cContent.ToLower().IndexOf(""", iIndex + 2);
src = cContent.Substring(iIndex, iEnd - iIndex);
src = src.Replace(""", "").Replace("src=", "");
}
else
{
src = "";
}
}
catch (Exception ex)
{
src = ex.Message + "(" + iIndex + "," + iEnd + ")";
}
return src;
}
#endregion
#region 获取文章的media_id
/// <summary>
/// 请求Url,发送数据
/// </summary>
public static string PostUrl(string url, string postData)
{
byte[] data = Encoding.UTF8.GetBytes(postData);
// 设置参数
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = data.Length;
Stream outstream = request.GetRequestStream();
outstream.Write(data, 0, data.Length);
outstream.Close();
//发送请求并获取相应回应数据
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
//直到request.GetResponse()程序才开始向目标网页发送Post请求
Stream instream = response.GetResponseStream();
StreamReader sr = new StreamReader(instream, Encoding.UTF8);
//返回结果网页(html)代码
string content = sr.ReadToEnd();
return content;
}
/// <summary>
/// 上传图文消息素材获取media_id
/// </summary>
/// <param name="access_token">微信的access_token</param>
/// <param name="postData">拼接好的微信文章json数据</param>
/// <returns>media_id</returns>
public string UploadNews(string access_token, string postData)
{
string content = "";
content = PostUrl(string.Format("https://api.weixin.qq.com/cgi-bin/media/uploadnews?access_token={0}", access_token), postData);
if (_regex.IsMatch(content))
content = _regex.Match(content).Value;
var result = JsonConvert.DeserializeObject<Get_Media_Id>(content);
string media_id = result.Media_ID;
string type = result.Type;
string create_at = result.Created_At;
return media_id;
}
#endregion
#region 获取所有关注者的openid
/// <summary>
/// 获取关注者OpenID集合
/// </summary>
/// <param name="access_token">微信获取的access_token</param>
/// <param name="redirect_uri">请求获取openid的页面地址</param>
/// <returns>OpenID集合</returns>
public List<string> GetOpenIDs(string access_token, string redirect_uri)
{
List<string> result = new List<string>();
List<string> openidList = GetOpenIDs(access_token, null, redirect_uri);
result.AddRange(openidList);
while (openidList.Count > 9999)
{
openidList = GetOpenIDs(access_token, openidList[openidList.Count - 1], redirect_uri);
if (openidList.Count > 0)
result.AddRange(openidList);
}
return result;
}
/// <summary>
/// 获取关注者OpenID集合
/// </summary>
public List<string> GetOpenIDs(string access_token, string next_openid,string redirect_uri)
{
// 设置参数
HttpHelper helper = new HttpHelper();
string url = string.Format("https://api.weixin.qq.com/cgi-bin/user/get?access_token={0}&next_openid={1}", access_token, string.IsNullOrWhiteSpace(next_openid) ? "" : next_openid);
string returnStr = helper.GetPageResponse_Get(url, redirect_uri, "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
List<string> list = new List<string>();
var result_list = JsonConvert.DeserializeObject<Get_OpenID>(returnStr);
if (result_list.Data.OpenID.Length > 0)
{
string[] resule_data = result_list.Data.OpenID;
list.AddRange(resule_data);
}
return list;
}
#endregion
#region 拼接图文消息
/// <summary>
/// 拼接图文消息json
/// </summary>
/// <param name="media_id"></param>
/// <param name="openidList"></param>
/// <returns></returns>
public string CreateNewsJson(string media_id, List<string> openidList)
{
StringBuilder sb = new StringBuilder();
sb.Append("{"touser":[");
sb.Append(string.Join(",", openidList.ConvertAll<string>(a => """ + a + """).ToArray()));
sb.Append("],");
sb.Append(""mpnews":{"media_id":"" + media_id + ""},");
sb.Append(""msgtype":"mpnews"");
sb.Append("}");
return sb.ToString();
}
/// <summary>
/// 拼接图文消息(用于预览),只能使用单一的微信号或者微信openid,需手动更改
/// </summary>
/// <param name="media_id"></param>
/// <returns></returns>
public string CreateNewsJson2(string media_id)
{
BSet b = new BSet("9000");
StringBuilder sb = new StringBuilder();
sb.Append("{"towxname":""+b.cCode2+"",");
sb.Append(""msgtype":"mpnews",");
sb.Append(""mpnews":{"media_id":"" + media_id + ""}");
sb.Append("}");
return sb.ToString();
}
/// <summary>
/// 根据OpenID列表群发
/// </summary>
public string Send(string access_token, string postData, string redirect_uri)
{
HttpHelper helper = new HttpHelper();
return helper.GetPageResponse_Post(string.Format("https://api.weixin.qq.com/cgi-bin/message/mass/send?access_token={0}", access_token), postData, redirect_uri);
}
#endregion
#region 微信接口预览
/// <summary>
/// 预览接口
/// </summary>
/// <param name="access_token">access_token</param>
/// <param name="media_id">消息的media_id</param>
/// <param name="openidList">用户openidList数组</param>
/// <param name="redirect_uri">请求页面的地址</param>
/// <param name="postData">文章内容</param>
/// <returns></returns>
public string previewMsg(string access_token, string postData, string redirect_uri)
{
HttpHelper helper = new HttpHelper();
return helper.GetPageResponse_Post(string.Format("https://api.weixin.qq.com/cgi-bin/message/mass/preview?access_token={0}", access_token), postData, redirect_uri);
}
#endregion
#region Utility
/// <summary>
/// 生成随机字母字符串(数字字母混和)
/// </summary>
public static string GenerateCheckCode()
{
int rep = 0;
string str = string.Empty;
long num2 = DateTime.Now.Ticks + rep;
rep++;
Random random = new Random(((int)(((ulong)num2) & 0xffffffffL)) | ((int)(num2 >> rep)));
for (int i = 0; i < 15; i++)
{
char ch;
int num = random.Next();
if ((num % 2) == 0)
{
ch = (char)(0x30 + ((ushort)(num % 10)));
}
else
{
ch = (char)(0x41 + ((ushort)(num % 0x1a)));
}
str = str + ch.ToString();
}
return str;
}
/// <summary>
/// 获取没有图片的文章内容
/// </summary>
public string GetNoPicarticle(string content) {
string str = "<img(.*?)(src)="(?!.*?logo).*>";
Regex regex = new Regex(str);
foreach(Match re in regex.Matches(content)){
content = content.Replace(re.Value, "");
}
content = content.Replace(""", "‘").Replace("<p>","").Replace("</p>","");
content = content.Replace("<label>", "").Replace("</label>", "").Replace("<span>", "</span>");
return content;
}
/// <summary>
/// 替换文章内的图片链接
/// </summary>
/// <returns></returns>
public string GetReplacePic(string content, string access_token)
{
string str = @"<img.*?src=""([^""]*)"".*?>";
Regex regex = new Regex(str);
foreach (Match re in regex.Matches(content))//匹配出所有src
{
////获取图片在微信的url
string wx_url = UploadImg(access_token, HttpContext.Current.Server.MapPath(re.Groups[1].Value));
if (_regex.IsMatch(wx_url))
wx_url = _regex.Match(wx_url).Value;
var result_url = JsonConvert.DeserializeObject<Get_ImgUrl>(wx_url);
string url = result_url.URL;
string result = re.Groups[1].Value.Replace(re.Groups[1].Value, url);
content = content.Replace(re.Groups[1].Value, result);
}
content = content.Replace(""", "‘");
return content;
}
#endregion
#region Json
//Json解析
public class Get_Access_token
{
[JsonProperty("access_token")]
public string Access_Token { get; set; }
[JsonProperty("expires_in")]
public string Expires_In { get; set; }
}
public class ErrorCode
{
[JsonProperty("errcode")]
public string ErrCode { get; set; }
[JsonProperty("errmsg")]
public string ErrMsg { get; set; }
[JsonProperty("msg_id")]
public string Msg_ID { get; set; }
[JsonProperty("msg_data_id")]
public string Msg_Data_ID { get; set; }
}
public class Get_Media_Id
{
// 媒体文件类型,分别有图片(image)、语音(voice)、视频(video)和缩略图(thumb),次数为news,即图文消息
[JsonProperty("type")]
public string Type { get; set; }
// 媒体文件/图文消息上传后获取的唯一标识
[JsonProperty("media_id")]
public string Media_ID { get; set; }
// 媒体文件上传时间
[JsonProperty("created_at")]
public string Created_At { get; set; }
// [JsonProperty("thumb_media_id")]
//public string Thumb_media_id { get; set; }
}
public class Get_OpenID
{
//媒体文件类型ID
[JsonProperty("total")]
public string Total { get; set; }
[JsonProperty("count")]
public string Count { get; set; }
[JsonProperty("data")]
public Get_OpenIDs Data { get; set; }
[JsonProperty("next_openid")]
public string Next_Openid { get; set; }
}
public class Get_OpenIDs
{
//关注者列表ID
[JsonProperty("openid")]
public string[] OpenID { get; set; }
}
public class Get_ImgUrl
{
//图片在微信的地址
[JsonProperty("url")]
public string URL { get; set; }
}
#endregion
}
}