xtyga330024

asp.net 模拟CURL调用微信公共平台API 上传下载多媒体文件

近公司项目上在开发微信服务号的接口,需要给用户回复图片或语音或视频,这个时候就需要用到 上传下载多媒体文件接口,微信在这方面推荐采用的是开源函数库curl实现的,CURL项目包括很多版本,我主要测试的是windows 平台下的版本,是很好用的,下面附上说明及CURL下载地址

在asp.net中,可以调用cmd命令行,运行这个脚本,实现上传下载的功能,但我需要讲的重点不在此,做为一个在线运行的项目,允许网站目录下可以运行.exe的程序是非常不安全的,所以接下来的DEMO是采用asp.net(c#)的方式,调用微信的这个API接口

不多说,上代码

总共有二个类,一个枚举

FormItem类
 

 


public class FormItem

{

public string Name { get; set; }

public ParamType ParamType { get; set; }

public string Value { get; set; }

}

ParamType枚举
 

public enum ParamType



///

/// 文本类型

///

Text,

///

/// 文件路径,需要全路径(例:C:\A.JPG)

///

File

}

Funcs静态类
 

public static class Funcs

{
 

public static string PostFormData(List list,string uri)

{

string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");

//请求 

WebRequest req = WebRequest.Create(uri);

req.Method = "POST";

req.ContentType = "multipart/form-data; boundary=" + boundary;

//组织表单数据 

StringBuilder sb = new StringBuilder();

foreach (FormItem item in list)

{

switch (item.ParamType)

{

case ParamType.Text:

sb.Append("--" + boundary);

sb.Append("\r\n");

sb.Append("Content-Disposition: form-data; name="" + item.Name + """);

sb.Append("\r\n\r\n");

sb.Append(item.Value);

sb.Append("\r\n");

break;

case ParamType.File:

sb.Append("--" + boundary);

sb.Append("\r\n");

sb.Append("Content-Disposition: form-data; name="media"; filename=""+item.Value+""");

sb.Append("\r\n");

sb.Append("Content-Type: application/octet-stream");

sb.Append("\r\n\r\n");

break;

}

}

string head = sb.ToString();

//post字节总长度

long length = 0;

byte[] form_data = Encoding.UTF8.GetBytes(head);

//结尾 

byte[] foot_data = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n");

List fileList = list.Where(f => f.ParamType == ParamType.File).ToList();

length = form_data.Length + foot_data.Length;

foreach (FormItem fi in fileList)

{

FileStream fileStream = new FileStream(fi.Value, FileMode.Open, FileAccess.Read);

length += fileStream.Length;

fileStream.Close();

}

req.ContentLength = length; 
 

 

Stream requestStream = req.GetRequestStream();

//发送表单参数 

requestStream.Write(form_data, 0, form_data.Length);

foreach (FormItem fd in fileList)

{

FileStream fileStream = new FileStream(fd.Value, FileMode.Open, FileAccess.Read);

//文件内容 

byte[] buffer = new Byte[checked((uint)Math.Min(4096, (int)fileStream.Length))];

int bytesRead = 0;

while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)

requestStream.Write(buffer, 0, bytesRead);

//结尾 

requestStream.Write(foot_data, 0, foot_data.Length);

}

requestStream.Close();
 

 

//响应 

WebResponse pos = req.GetResponse();

StreamReader sr = new StreamReader(pos.GetResponseStream(), Encoding.UTF8);

string html = sr.ReadToEnd().Trim();

sr.Close();

if (pos != null)

{

pos.Close();

pos = null;

}

if (req != null)

{

req = null;

}

return html;

}

///

/// 从URL地址下载文件到本地磁盘

///

/// 本地磁盘地址

/// URL网址

///

public static string SaveFileFromUrl(string FileName, string Url)

{

WebResponse response = null;

Stream stream = null;

try

{

HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);

response = request.GetResponse();

stream = response.GetResponseStream();
 

 

if (!response.ContentType.ToLower().StartsWith("text/"))

{

SaveBinaryFile(response, FileName);

}

else

{

StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8);

return sr.ReadToEnd();

}
 

 

}

catch (Exception err)

{

return err.ToString();

}

return "complete";

}

///

/// 将二进制文件保存到磁盘

///

/// 将二进制文件保存到磁盘

// 将二进制文件保存到磁盘

private static bool SaveBinaryFile(WebResponse response, string FileName)

{

bool Value = true;

byte[] buffer = new byte[1024];
 

 

try

{

if (File.Exists(FileName))

File.Delete(FileName);

Stream outStream = System.IO.File.Create(FileName);

Stream inStream = response.GetResponseStream();
 

 

int l;

do

{

l = inStream.Read(buffer, 0, buffer.Length);

if (l > 0)

outStream.Write(buffer, 0, l);

}

while (l > 0);
 

 

outStream.Close();

inStream.Close();

}

catch

{

Value = false;

}

return Value;

}

}

调用代码
 

 

//新建一个form表单项,就是需要提交哪些字段和数据的列表
 

List list = new List();

//添加微信接口上的access_token参数,注意,access_token是有过期时间的,代码中的access_token肯定过期了,获取access_token的地址请点击我,需要有自己的服务号才会有的

list.Add(new FormItem() { Name = "access_token", ParamType =

ParamType.Text, Value = "MlfTORyg_dRTuiQThmKUxVVkK7q_SMEd0y9GwBmj6NJw3E0J

2jVnC3RxgdO1Yjog2QD4DDxhdqEkZaklR7czq8sSbW4mnhM7n9-5lIIymVGkrBAv2nnnk

tUyYcuYTMs2SYtp-pn6IWEtTpsFVlUFZQ" });

//添加FORM表单中这条数据的类型,目前只做了两种,一种是文本,一种是文件

list.Add(new FormItem() { Name = "type", Value = "image", ParamType = ParamType.Text });

//添加Form表单中文件的路径,路径必须是基于硬盘的绝对路径

list.Add(new FormItem() { Name = "media", Value = @"d:\1.jpg", ParamType = ParamType.File });

//通过Funcs静态类中的PostFormData方法,将表单数据发送至https://file.api.weixin.qq.com/cgi-bin/media/upload腾讯上传下载文件接口

string result = Funcs.PostFormData(list, "https://file.api.weixin.qq.com/cgi-bin/media/upload");

//获取返回值,并取出的结果中的media_id,注意,有可能返回的是腾讯的错误代码,请自行判断

System.Web.Script.Serialization.JavaScriptSerializer jss = new System.Web.Script.Serialization.JavaScriptSerializer();

var mydata=jss.Deserialize(result);

//通过Funcs静态类中的SaveFileFromUrl方法,将指定微信media_id的文件下载到本机

var saveResult=Funcs.SaveFileFromUrl(@"d:\lee.jpg", "https://file.api.weixin.qq.com/cgi-bin/media/get?access_token=MlfTORyg_dRTuiQThmKUxVVkK7q_SMEd0y9GwBmj6NJw3E0J2jVnC3RxgdO1Yjog2QD4DDxhdqEkZaklR7czq8sSbW4mnhM7n9-5lIIymVGkrBAv2nnnktUyYcuYTMs2SYtp-pn6IWEtTpsFVlUFZQ&media_id=" + mydata["media_id"].ToString());
 

 

这样就完成了模拟CURL调用微信上传下载多媒体文件的接口

评论