dr.*_*vil 296 .net upload httpwebrequest
是否有任何类,库或一些代码可以帮助我使用HTTPWebrequest上传文件?
编辑2:
我不想上传到WebDAV文件夹或类似的东西.我想模拟浏览器,就像您将头像上传到论坛或通过Web应用程序中的表单上传文件一样.上传到使用multipart/form-data的表单.
编辑:
WebClient不能满足我的要求,所以我正在寻找HTTPWebrequest的解决方案.
小智 249
取得上面的代码并修复,因为它会引发内部服务器错误500.\r \n定位错误和空间等存在一些问题.应用重构与内存流,直接写入请求流.结果如下:
public static void HttpUploadFile(string url, string file, string paramName, string contentType, NameValueCollection nvc) {
log.Debug(string.Format("Uploading {0} to {1}", file, url));
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.KeepAlive = true;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
Stream rs = wr.GetRequestStream();
string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
foreach (string key in nvc.Keys)
{
rs.Write(boundarybytes, 0, boundarybytes.Length);
string formitem = string.Format(formdataTemplate, key, nvc[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
rs.Write(formitembytes, 0, formitembytes.Length);
}
rs.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
string header = string.Format(headerTemplate, paramName, file, contentType);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
rs.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) {
rs.Write(buffer, 0, bytesRead);
}
fileStream.Close();
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
rs.Write(trailer, 0, trailer.Length);
rs.Close();
WebResponse wresp = null;
try {
wresp = wr.GetResponse();
Stream stream2 = wresp.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
log.Debug(string.Format("File uploaded, server response is: {0}", reader2.ReadToEnd()));
} catch(Exception ex) {
log.Error("Error uploading file", ex);
if(wresp != null) {
wresp.Close();
wresp = null;
}
} finally {
wr = null;
}
}
Run Code Online (Sandbox Code Playgroud)
和样品用法:
NameValueCollection nvc = new NameValueCollection();
nvc.Add("id", "TTR");
nvc.Add("btn-submit-photo", "Upload");
HttpUploadFile("http://your.server.com/upload",
@"C:\test\test.jpg", "file", "image/jpeg", nvc);
Run Code Online (Sandbox Code Playgroud)
它可以扩展为处理多个文件,或者只为每个文件多次调用它.但它适合您的需求.
dr.*_*vil 141
我正在寻找这样的东西,发现于:http: //bytes.com/groups/net-c/268661-how-upload-file-via-c-code(为正确性而修改):
public static string UploadFilesToRemoteUrl(string url, string[] files, NameValueCollection formFields = null)
{
string boundary = "----------------------------" + DateTime.Now.Ticks.ToString("x");
HttpWebRequest request = (HttpWebRequest) WebRequest.Create(url);
request.ContentType = "multipart/form-data; boundary=" +
boundary;
request.Method = "POST";
request.KeepAlive = true;
Stream memStream = new System.IO.MemoryStream();
var boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "\r\n");
var endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" +
boundary + "--");
string formdataTemplate = "\r\n--" + boundary +
"\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";
if (formFields != null)
{
foreach (string key in formFields.Keys)
{
string formitem = string.Format(formdataTemplate, key, formFields[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
memStream.Write(formitembytes, 0, formitembytes.Length);
}
}
string headerTemplate =
"Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" +
"Content-Type: application/octet-stream\r\n\r\n";
for (int i = 0; i < files.Length; i++)
{
memStream.Write(boundarybytes, 0, boundarybytes.Length);
var header = string.Format(headerTemplate, "uplTheFile", files[i]);
var headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
memStream.Write(headerbytes, 0, headerbytes.Length);
using (var fileStream = new FileStream(files[i], FileMode.Open, FileAccess.Read))
{
var buffer = new byte[1024];
var bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
}
}
memStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
request.ContentLength = memStream.Length;
using (Stream requestStream = request.GetRequestStream())
{
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
}
using (var response = request.GetResponse())
{
Stream stream2 = response.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
return reader2.ReadToEnd();
}
}
Run Code Online (Sandbox Code Playgroud)
Jos*_*des 103
更新:使用.NET 4.5(或通过添加NuGet 的Microsoft.Net.Http软件包进行.NET 4.0 ),无需外部代码,扩展和"低级"HTTP操作即可实现.这是一个例子:
// Perform the equivalent of posting a form with a filename and two files, in HTML:
// <form action="{url}" method="post" enctype="multipart/form-data">
// <input type="text" name="filename" />
// <input type="file" name="file1" />
// <input type="file" name="file2" />
// </form>
private async Task<System.IO.Stream> UploadAsync(string url, string filename, Stream fileStream, byte [] fileBytes)
{
// Convert each of the three inputs into HttpContent objects
HttpContent stringContent = new StringContent(filename);
// examples of converting both Stream and byte [] to HttpContent objects
// representing input type file
HttpContent fileStreamContent = new StreamContent(fileStream);
HttpContent bytesContent = new ByteArrayContent(fileBytes);
// Submit the form using HttpClient and
// create form data as Multipart (enctype="multipart/form-data")
using (var client = new HttpClient())
using (var formData = new MultipartFormDataContent())
{
// Add the HttpContent objects to the form data
// <input type="text" name="filename" />
formData.Add(stringContent, "filename", "filename");
// <input type="file" name="file1" />
formData.Add(fileStreamContent, "file1", "file1");
// <input type="file" name="file2" />
formData.Add(bytesContent, "file2", "file2");
// Invoke the request to the server
// equivalent to pressing the submit button on
// a form with attributes (action="{url}" method="post")
var response = await client.PostAsync(url, formData);
// ensure the request was a success
if (!response.IsSuccessStatusCode)
{
return null;
}
return await response.Content.ReadAsStreamAsync();
}
}
Run Code Online (Sandbox Code Playgroud)
Chr*_*nes 16
我的ASP.NET上传常见问题解答中有一篇文章,其中包含示例代码:使用带有HttpWebRequest/WebClient的RFC 1867 POST请求上传文件.此代码不会将文件加载到内存中(与上面的代码相反),支持多个文件,并支持表单值,设置凭据和cookie等.
编辑:看起来像Axosoft取下页面.多谢你们.
它仍然可以通过archive.org访问.
Ste*_*fan 14
根据上面提供的代码,我添加了对多个文件的支持,并且还可以直接上传流而无需拥有本地文件.
要将文件上传到包含一些邮政参数的特定网址,请执行以下操作:
RequestHelper.PostMultipart(
"http://www.myserver.com/upload.php",
new Dictionary<string, object>() {
{ "testparam", "my value" },
{ "file", new FormFile() { Name = "image.jpg", ContentType = "image/jpeg", FilePath = "c:\\temp\\myniceimage.jpg" } },
{ "other_file", new FormFile() { Name = "image2.jpg", ContentType = "image/jpeg", Stream = imageDataStream } },
});
Run Code Online (Sandbox Code Playgroud)
为了增强这一点,可以从给定文件本身确定名称和mime类型.
public class FormFile
{
public string Name { get; set; }
public string ContentType { get; set; }
public string FilePath { get; set; }
public Stream Stream { get; set; }
}
public class RequestHelper
{
public static string PostMultipart(string url, Dictionary<string, object> parameters) {
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.ContentType = "multipart/form-data; boundary=" + boundary;
request.Method = "POST";
request.KeepAlive = true;
request.Credentials = System.Net.CredentialCache.DefaultCredentials;
if(parameters != null && parameters.Count > 0) {
using(Stream requestStream = request.GetRequestStream()) {
foreach(KeyValuePair<string, object> pair in parameters) {
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length);
if(pair.Value is FormFile) {
FormFile file = pair.Value as FormFile;
string header = "Content-Disposition: form-data; name=\"" + pair.Key + "\"; filename=\"" + file.Name + "\"\r\nContent-Type: " + file.ContentType + "\r\n\r\n";
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(header);
requestStream.Write(bytes, 0, bytes.Length);
byte[] buffer = new byte[32768];
int bytesRead;
if(file.Stream == null) {
// upload from file
using(FileStream fileStream = File.OpenRead(file.FilePath)) {
while((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
fileStream.Close();
}
}
else {
// upload from given stream
while((bytesRead = file.Stream.Read(buffer, 0, buffer.Length)) != 0)
requestStream.Write(buffer, 0, bytesRead);
}
}
else {
string data = "Content-Disposition: form-data; name=\"" + pair.Key + "\"\r\n\r\n" + pair.Value;
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(data);
requestStream.Write(bytes, 0, bytes.Length);
}
}
byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
requestStream.Write(trailer, 0, trailer.Length);
requestStream.Close();
}
}
using(WebResponse response = request.GetResponse()) {
using(Stream responseStream = response.GetResponseStream())
using(StreamReader reader = new StreamReader(responseStream))
return reader.ReadToEnd();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Moo*_*ose 11
这样的事情很接近:(未经测试的代码)
byte[] data; // data goes here.
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Credentials = userNetworkCredentials;
request.Method = "PUT";
request.ContentType = "application/octet-stream";
request.ContentLength = data.Length;
Stream stream = request.GetRequestStream();
stream.Write(data,0,data.Length);
stream.Close();
response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());
temp = reader.ReadToEnd();
reader.Close();
Run Code Online (Sandbox Code Playgroud)
小智 6
采取上述并修改它接受一些标头值和多个文件
NameValueCollection headers = new NameValueCollection();
headers.Add("Cookie", "name=value;");
headers.Add("Referer", "http://google.com");
NameValueCollection nvc = new NameValueCollection();
nvc.Add("name", "value");
HttpUploadFile(url, new string[] { "c:\\file1.txt", "c:\\file2.jpg" }, new string[] { "file", "image" }, new string[] { "application/octet-stream", "image/jpeg" }, nvc, headers);
Run Code Online (Sandbox Code Playgroud)
public static void HttpUploadFile(string url, string[] file, string[] paramName, string[] contentType, NameValueCollection nvc, NameValueCollection headerItems)
{
//log.Debug(string.Format("Uploading {0} to {1}", file, url));
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
foreach (string key in headerItems.Keys)
{
if (key == "Referer")
{
wr.Referer = headerItems[key];
}
else
{
wr.Headers.Add(key, headerItems[key]);
}
}
wr.ContentType = "multipart/form-data; boundary=" + boundary;
wr.Method = "POST";
wr.KeepAlive = true;
wr.Credentials = System.Net.CredentialCache.DefaultCredentials;
Stream rs = wr.GetRequestStream();
string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
foreach (string key in nvc.Keys)
{
rs.Write(boundarybytes, 0, boundarybytes.Length);
string formitem = string.Format(formdataTemplate, key, nvc[key]);
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
rs.Write(formitembytes, 0, formitembytes.Length);
}
rs.Write(boundarybytes, 0, boundarybytes.Length);
string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
string header = "";
for(int i =0; i<file.Count();i++)
{
header = string.Format(headerTemplate, paramName[i], System.IO.Path.GetFileName(file[i]), contentType[i]);
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
rs.Write(headerbytes, 0, headerbytes.Length);
FileStream fileStream = new FileStream(file[i], FileMode.Open, FileAccess.Read);
byte[] buffer = new byte[4096];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
rs.Write(buffer, 0, bytesRead);
}
fileStream.Close();
rs.Write(boundarybytes, 0, boundarybytes.Length);
}
rs.Close();
WebResponse wresp = null;
try
{
wresp = wr.GetResponse();
Stream stream2 = wresp.GetResponseStream();
StreamReader reader2 = new StreamReader(stream2);
//log.Debug(string.Format("File uploaded, server response is: {0}", reader2.ReadToEnd()));
}
catch (Exception ex)
{
//log.Error("Error uploading file", ex);
wresp.Close();
wresp = null;
}
finally
{
wr = null;
}
}
Run Code Online (Sandbox Code Playgroud)
VB示例(在另一篇文章中从C#示例转换):
Private Sub HttpUploadFile( _
ByVal uri As String, _
ByVal filePath As String, _
ByVal fileParameterName As String, _
ByVal contentType As String, _
ByVal otherParameters As Specialized.NameValueCollection)
Dim boundary As String = "---------------------------" & DateTime.Now.Ticks.ToString("x")
Dim newLine As String = System.Environment.NewLine
Dim boundaryBytes As Byte() = Text.Encoding.ASCII.GetBytes(newLine & "--" & boundary & newLine)
Dim request As Net.HttpWebRequest = Net.WebRequest.Create(uri)
request.ContentType = "multipart/form-data; boundary=" & boundary
request.Method = "POST"
request.KeepAlive = True
request.Credentials = Net.CredentialCache.DefaultCredentials
Using requestStream As IO.Stream = request.GetRequestStream()
Dim formDataTemplate As String = "Content-Disposition: form-data; name=""{0}""{1}{1}{2}"
For Each key As String In otherParameters.Keys
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)
Dim formItem As String = String.Format(formDataTemplate, key, newLine, otherParameters(key))
Dim formItemBytes As Byte() = Text.Encoding.UTF8.GetBytes(formItem)
requestStream.Write(formItemBytes, 0, formItemBytes.Length)
Next key
requestStream.Write(boundaryBytes, 0, boundaryBytes.Length)
Dim headerTemplate As String = "Content-Disposition: form-data; name=""{0}""; filename=""{1}""{2}Content-Type: {3}{2}{2}"
Dim header As String = String.Format(headerTemplate, fileParameterName, filePath, newLine, contentType)
Dim headerBytes As Byte() = Text.Encoding.UTF8.GetBytes(header)
requestStream.Write(headerBytes, 0, headerBytes.Length)
Using fileStream As New IO.FileStream(filePath, IO.FileMode.Open, IO.FileAccess.Read)
Dim buffer(4096) As Byte
Dim bytesRead As Int32 = fileStream.Read(buffer, 0, buffer.Length)
Do While (bytesRead > 0)
requestStream.Write(buffer, 0, bytesRead)
bytesRead = fileStream.Read(buffer, 0, buffer.Length)
Loop
End Using
Dim trailer As Byte() = Text.Encoding.ASCII.GetBytes(newLine & "--" + boundary + "--" & newLine)
requestStream.Write(trailer, 0, trailer.Length)
End Using
Dim response As Net.WebResponse = Nothing
Try
response = request.GetResponse()
Using responseStream As IO.Stream = response.GetResponseStream()
Using responseReader As New IO.StreamReader(responseStream)
Dim responseText = responseReader.ReadToEnd()
Diagnostics.Debug.Write(responseText)
End Using
End Using
Catch exception As Net.WebException
response = exception.Response
If (response IsNot Nothing) Then
Using reader As New IO.StreamReader(response.GetResponseStream())
Dim responseText = reader.ReadToEnd()
Diagnostics.Debug.Write(responseText)
End Using
response.Close()
End If
Finally
request = Nothing
End Try
End Sub
Run Code Online (Sandbox Code Playgroud)