What is the easiest way to submit an HTTP POST request with a multipart/form-data content type from C#? There has to be a better way than building my own request.
使用C#中的multipart / form-data内容类型提交HTTP POST请求的最简单方法是什么?必须有一个比建立我自己的请求更好的方法。
The reason I'm asking is to upload photos to Flickr using this api:
我问的原因是使用这个api将照片上传到Flickr:
http://www.flickr.com/services/api/upload.api.html
6 个解决方案
#1
1
First of all, there's nothing wrong with pure manual implementation of the HTTP commands using the .Net framework. Do keep in mind that it's a framework, and it is supposed to be pretty generic.
首先,使用.Net框架纯手动实现HTTP命令没有任何问题。请记住,它是一个框架,它应该是非常通用的。
Secondly, I think you can try searching for a browser implementation in .Net. I saw this one, perhaps it covers the issue you asked about. Or you can just search for "C# http put get post request". One of the results leads to a non-free library that may be helpful (Chilkat Http)
其次,我认为您可以尝试在.Net中搜索浏览器实现。我看到了这个,也许它涵盖了你所问的问题。或者你可以只搜索“C#http put get post request”。其中一个结果导致非*库可能有所帮助(Chilkat Http)
If you happen to write your own framework of HTTP commands on top of .Net - I think we can all enjoy it if you share it :-)
如果您碰巧在.Net上编写自己的HTTP命令框架 - 我想如果您分享它,我们都可以享受它:-)
#2
5
If you are using .NET 4.5 use this:
如果您使用的是.NET 4.5,请使用以下命令:
public string Upload(string url, NameValueCollection requestParameters, MemoryStream file)
{
var client = new HttpClient();
var content = new MultipartFormDataContent();
content.Add(new StreamContent(file));
System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string, string>> b = new List<KeyValuePair<string, string>>();
b.Add(requestParameters);
var addMe = new FormUrlEncodedContent(b);
content.Add(addMe);
var result = client.PostAsync(url, content);
return result.Result.ToString();
}
Otherwise Based on Ryan's answer, I downloaded the library and tweaked it a bit.
否则根据Ryan的回答,我下载了库并稍微调整了一下。
public class MimePart
{
NameValueCollection _headers = new NameValueCollection();
byte[] _header;
public NameValueCollection Headers
{
get { return _headers; }
}
public byte[] Header
{
get { return _header; }
}
public long GenerateHeaderFooterData(string boundary)
{
StringBuilder sb = new StringBuilder();
sb.Append("--");
sb.Append(boundary);
sb.AppendLine();
foreach (string key in _headers.AllKeys)
{
sb.Append(key);
sb.Append(": ");
sb.AppendLine(_headers[key]);
}
sb.AppendLine();
_header = Encoding.UTF8.GetBytes(sb.ToString());
return _header.Length + Data.Length + 2;
}
public Stream Data { get; set; }
}
public string Upload(string url, NameValueCollection requestParameters, params MemoryStream[] files)
{
using (WebClient req = new WebClient())
{
List<MimePart> mimeParts = new List<MimePart>();
try
{
foreach (string key in requestParameters.AllKeys)
{
MimePart part = new MimePart();
part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
part.Data = new MemoryStream(Encoding.UTF8.GetBytes(requestParameters[key]));
mimeParts.Add(part);
}
int nameIndex = 0;
foreach (MemoryStream file in files)
{
MimePart part = new MimePart();
string fieldName = "file" + nameIndex++;
part.Headers["Content-Disposition"] = "form-data; name=\"" + fieldName + "\"; filename=\"" + fieldName + "\"";
part.Headers["Content-Type"] = "application/octet-stream";
part.Data = file;
mimeParts.Add(part);
}
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
req.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary);
long contentLength = 0;
byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
foreach (MimePart part in mimeParts)
{
contentLength += part.GenerateHeaderFooterData(boundary);
}
//req.ContentLength = contentLength + _footer.Length;
byte[] buffer = new byte[8192];
byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
int read;
using (MemoryStream s = new MemoryStream())
{
foreach (MimePart part in mimeParts)
{
s.Write(part.Header, 0, part.Header.Length);
while ((read = part.Data.Read(buffer, 0, buffer.Length)) > 0)
s.Write(buffer, 0, read);
part.Data.Dispose();
s.Write(afterFile, 0, afterFile.Length);
}
s.Write(_footer, 0, _footer.Length);
byte[] responseBytes = req.UploadData(url, s.ToArray());
string responseString = Encoding.UTF8.GetString(responseBytes);
return responseString;
}
}
catch
{
foreach (MimePart part in mimeParts)
if (part.Data != null)
part.Data.Dispose();
throw;
}
}
}
#3
2
I've had success with the code posted at aspnetupload.com. I ended up making my own version of their UploadHelper library which is compatible with the Compact Framework. Works well, seems to do exactly what you require.
我在aspnetupload.com上发布的代码取得了成功。我最终创建了自己的UploadHelper库版本,该库与Compact Framework兼容。效果很好,似乎完全符合您的要求。
#4
2
I have not tried this myself, but there seems to be a built-in way in C# for this (although not a very known one apparently...):
我自己没有试过这个,但是在C#中似乎有一个内置的方式(虽然显然不是一个非常知名的......):
private static HttpClient _client = null;
private static void UploadDocument()
{
// Add test file
var httpContent = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(File.ReadAllBytes(@"File.jpg"));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "File.jpg"
};
httpContent.Add(fileContent);
string requestEndpoint = "api/Post";
var response = _client.PostAsync(requestEndpoint, httpContent).Result;
if (response.IsSuccessStatusCode)
{
// ...
}
else
{
// Check response.StatusCode, response.ReasonPhrase
}
}
Try it out and let me know how it goes.
尝试一下,让我知道它是怎么回事。
Cheers!
#5
1
The System.Net.WebClient class may be what you are looking for. Check the documentation for WebClient.UploadFile, it should allow you to upload a file to a specified resource via one of the UploadFile overloads. I think this is the method you are looking to use to post the data...
System.Net.WebClient类可能正是您要查找的内容。检查WebClient.UploadFile的文档,它应该允许您通过UploadFile重载之一上传文件到指定的资源。我认为这是您希望用于发布数据的方法...
It can be used like.... note this is just sample code not tested...
它可以像......一样使用。注意这只是未经测试的示例代码...
WebClient webClient = new WebClient();
WebClient webClient = new WebClient();
webClient.UploadFile("http://www.url.com/ReceiveUploadedFile.aspx", "POST", @"c:\myfile.txt");
webClient.UploadFile(“http://www.url.com/ReceiveUploadedFile.aspx”,“POST”,@“c:\ myfile.txt”);
Here is the MSDN reference if you are interested.
如果您有兴趣,这是MSDN参考。
http://msdn.microsoft.com/en-us/library/system.net.webclient.uploadfile.aspx
Hope this helps.
希望这可以帮助。
#6
-1
I normally find Fiddler to be the best tool for that job. Very ease to create requests and it even generates some of the headers for you.
我通常认为Fiddler是这项工作的最佳工具。创建请求非常容易,甚至可以为您生成一些标题。
Fiddler - How to create a request
Fiddler - 如何创建请求
#1
1
First of all, there's nothing wrong with pure manual implementation of the HTTP commands using the .Net framework. Do keep in mind that it's a framework, and it is supposed to be pretty generic.
首先,使用.Net框架纯手动实现HTTP命令没有任何问题。请记住,它是一个框架,它应该是非常通用的。
Secondly, I think you can try searching for a browser implementation in .Net. I saw this one, perhaps it covers the issue you asked about. Or you can just search for "C# http put get post request". One of the results leads to a non-free library that may be helpful (Chilkat Http)
其次,我认为您可以尝试在.Net中搜索浏览器实现。我看到了这个,也许它涵盖了你所问的问题。或者你可以只搜索“C#http put get post request”。其中一个结果导致非*库可能有所帮助(Chilkat Http)
If you happen to write your own framework of HTTP commands on top of .Net - I think we can all enjoy it if you share it :-)
如果您碰巧在.Net上编写自己的HTTP命令框架 - 我想如果您分享它,我们都可以享受它:-)
#2
5
If you are using .NET 4.5 use this:
如果您使用的是.NET 4.5,请使用以下命令:
public string Upload(string url, NameValueCollection requestParameters, MemoryStream file)
{
var client = new HttpClient();
var content = new MultipartFormDataContent();
content.Add(new StreamContent(file));
System.Collections.Generic.List<System.Collections.Generic.KeyValuePair<string, string>> b = new List<KeyValuePair<string, string>>();
b.Add(requestParameters);
var addMe = new FormUrlEncodedContent(b);
content.Add(addMe);
var result = client.PostAsync(url, content);
return result.Result.ToString();
}
Otherwise Based on Ryan's answer, I downloaded the library and tweaked it a bit.
否则根据Ryan的回答,我下载了库并稍微调整了一下。
public class MimePart
{
NameValueCollection _headers = new NameValueCollection();
byte[] _header;
public NameValueCollection Headers
{
get { return _headers; }
}
public byte[] Header
{
get { return _header; }
}
public long GenerateHeaderFooterData(string boundary)
{
StringBuilder sb = new StringBuilder();
sb.Append("--");
sb.Append(boundary);
sb.AppendLine();
foreach (string key in _headers.AllKeys)
{
sb.Append(key);
sb.Append(": ");
sb.AppendLine(_headers[key]);
}
sb.AppendLine();
_header = Encoding.UTF8.GetBytes(sb.ToString());
return _header.Length + Data.Length + 2;
}
public Stream Data { get; set; }
}
public string Upload(string url, NameValueCollection requestParameters, params MemoryStream[] files)
{
using (WebClient req = new WebClient())
{
List<MimePart> mimeParts = new List<MimePart>();
try
{
foreach (string key in requestParameters.AllKeys)
{
MimePart part = new MimePart();
part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
part.Data = new MemoryStream(Encoding.UTF8.GetBytes(requestParameters[key]));
mimeParts.Add(part);
}
int nameIndex = 0;
foreach (MemoryStream file in files)
{
MimePart part = new MimePart();
string fieldName = "file" + nameIndex++;
part.Headers["Content-Disposition"] = "form-data; name=\"" + fieldName + "\"; filename=\"" + fieldName + "\"";
part.Headers["Content-Type"] = "application/octet-stream";
part.Data = file;
mimeParts.Add(part);
}
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
req.Headers.Add(HttpRequestHeader.ContentType, "multipart/form-data; boundary=" + boundary);
long contentLength = 0;
byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
foreach (MimePart part in mimeParts)
{
contentLength += part.GenerateHeaderFooterData(boundary);
}
//req.ContentLength = contentLength + _footer.Length;
byte[] buffer = new byte[8192];
byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
int read;
using (MemoryStream s = new MemoryStream())
{
foreach (MimePart part in mimeParts)
{
s.Write(part.Header, 0, part.Header.Length);
while ((read = part.Data.Read(buffer, 0, buffer.Length)) > 0)
s.Write(buffer, 0, read);
part.Data.Dispose();
s.Write(afterFile, 0, afterFile.Length);
}
s.Write(_footer, 0, _footer.Length);
byte[] responseBytes = req.UploadData(url, s.ToArray());
string responseString = Encoding.UTF8.GetString(responseBytes);
return responseString;
}
}
catch
{
foreach (MimePart part in mimeParts)
if (part.Data != null)
part.Data.Dispose();
throw;
}
}
}
#3
2
I've had success with the code posted at aspnetupload.com. I ended up making my own version of their UploadHelper library which is compatible with the Compact Framework. Works well, seems to do exactly what you require.
我在aspnetupload.com上发布的代码取得了成功。我最终创建了自己的UploadHelper库版本,该库与Compact Framework兼容。效果很好,似乎完全符合您的要求。
#4
2
I have not tried this myself, but there seems to be a built-in way in C# for this (although not a very known one apparently...):
我自己没有试过这个,但是在C#中似乎有一个内置的方式(虽然显然不是一个非常知名的......):
private static HttpClient _client = null;
private static void UploadDocument()
{
// Add test file
var httpContent = new MultipartFormDataContent();
var fileContent = new ByteArrayContent(File.ReadAllBytes(@"File.jpg"));
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "File.jpg"
};
httpContent.Add(fileContent);
string requestEndpoint = "api/Post";
var response = _client.PostAsync(requestEndpoint, httpContent).Result;
if (response.IsSuccessStatusCode)
{
// ...
}
else
{
// Check response.StatusCode, response.ReasonPhrase
}
}
Try it out and let me know how it goes.
尝试一下,让我知道它是怎么回事。
Cheers!
#5
1
The System.Net.WebClient class may be what you are looking for. Check the documentation for WebClient.UploadFile, it should allow you to upload a file to a specified resource via one of the UploadFile overloads. I think this is the method you are looking to use to post the data...
System.Net.WebClient类可能正是您要查找的内容。检查WebClient.UploadFile的文档,它应该允许您通过UploadFile重载之一上传文件到指定的资源。我认为这是您希望用于发布数据的方法...
It can be used like.... note this is just sample code not tested...
它可以像......一样使用。注意这只是未经测试的示例代码...
WebClient webClient = new WebClient();
WebClient webClient = new WebClient();
webClient.UploadFile("http://www.url.com/ReceiveUploadedFile.aspx", "POST", @"c:\myfile.txt");
webClient.UploadFile(“http://www.url.com/ReceiveUploadedFile.aspx”,“POST”,@“c:\ myfile.txt”);
Here is the MSDN reference if you are interested.
如果您有兴趣,这是MSDN参考。
http://msdn.microsoft.com/en-us/library/system.net.webclient.uploadfile.aspx
Hope this helps.
希望这可以帮助。
#6
-1
I normally find Fiddler to be the best tool for that job. Very ease to create requests and it even generates some of the headers for you.
我通常认为Fiddler是这项工作的最佳工具。创建请求非常容易,甚至可以为您生成一些标题。
Fiddler - How to create a request
Fiddler - 如何创建请求