知识点

相关文章

更多

最近更新

更多

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

2019-03-02 00:58|来源: 网路

近公司项目上在开发微信服务号的接口,需要给用户回复图片或语音或视频,这个时候就需要用到 上传下载多媒体文件接口,微信在这方面推荐采用的是开源函数库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方法,将表单数据发送至http://file.api.weixin.qq.com/cgi-bin/media/upload腾讯上传下载文件接口


string result = Funcs.PostFormData(list, "http://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", "http://file.api.weixin.qq.com/cgi-bin/media/get?access_token=MlfTORyg_dRTuiQThmKUxVVkK7q_SMEd0y9GwBmj6NJw3E0J2jVnC3RxgdO1Yjog2QD4DDxhdqEkZaklR7czq8sSbW4mnhM7n9-5lIIymVGkrBAv2nnnktUyYcuYTMs2SYtp-pn6IWEtTpsFVlUFZQ&media_id=" + mydata["media_id"].ToString());
  


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


不知道大家有没有其它更好或更方便的办法,欢迎与我讨论

如果有需要的朋友,调用过程中有问题,欢迎私信给我,我可以把DEMO发给他


转自:http://www.cnblogs.com/mili3/p/3942009

相关问答

更多
  • 说实话 从软件或代码角度 没辙 都是长连接 逃不掉的 只能从系统设计上去考虑,大致上会有以下这两种思路(基本上是都用的): 1、对于所有的上传的文件,根据随机生成的名称或code取hash用策略取模,分服务器存/取文件,保证不触及io瓶颈,内部文件同步策略自己考虑 2、对所有请求,分pop点分发,根据用户的物理地址选择相应较近的pop点处理请求(当前pop请求已满则顺延至下一pop点,依次类推)
  • 我想出了问题,iframe是一个单独的页面,而不是它所在的页面,所以我不得不将数据作为查询字符串传递,它工作正常。 i figured out the problem, the iframe is a seperate page than the page it resides in so i had to pass the data as querystrings and it worked fine.
  • 我解决了从NuGet(在Visual Studio 2012中)安装Zendesk API v2并使用以下连接字符串: https://company.zendesk.com/api/v2 代替 http://company.zendesk.com I solved installing Zendesk API v2 from NuGet (inside Visual Studio 2012) and using the following connection string: https://c ...
  • IoC容器:适用于任何应用程序 存储库与否?:取决于您的应用程序将执行的操作。 尝试使用相同的工具在同一设计中使用每个应用程序也是一种反模式,因此请询问更具体的问题。 单一责任原则是最重要的设计原则。 当你在任何地方使用它时,你的代码都是可测试的,但是当你不习惯它时,这是最难学的东西。 IoC container: useful for any application Repository or not?: depends on what your application will do. Trying t ...
  • 你可以从这里下载 。 You can download it from here.
  • 不知道你想要做什么 - 你是否试图同时提供下载文件和更新他们链接到的HTML页面? 这不是HTML的工作原理。 如果你想达到这个结果,那么你基本上必须渲染一个元数据重定向到HTML中返回的文件,这样页面将加载,然后下载开始(就像你会看到很多的下载网站)。 Not sure what you're trying to do - are you trying to simultaneously serve a download file and an update to the HTML page they l ...
  • 你根本不需要在VS中做任何配置。 安装ASP.NET MVC之后,您将获得一个名为ASP.NET MVC Web应用程序的新项目类型,这就是您的旅程开始的地方:) 一个开始的好地方就是这个小示例应用http://www.asp.net/learn/mvc/#MVC_SampleApp 在此之后,您应该了解ASP.NET MVC如何工作的基本概念 you dont need to do any configuration in VS at all. after you installed ASP.NET MV ...
  • 你发布了什么版本的ASP.Net? 通常,ASP.net会检查以确保在处理回发之前访问了表单。 可以使用页面声明中的enableViewStateMac =“false”禁用此行为。 http://msdn.microsoft.com/en-us/library/ydy4x04a.aspx What version of ASP.Net are you posting too? Normally ASP.net will check to make sure the form was visited bef ...
  • 我找到了解决方案! 无需传递MultiPartFormData,您需要做的就是将文件作为ByteArrayContent传递给PostAsyn: string path = "path/to/file"; var fileBytes = File.ReadAllBytes(path); var response = await client.PostAsync(defaultSolrExtractUri, new ByteArrayContent(fileBytes)); return response.C ...