是否有任何类,库或一些代码片段,将帮助我上传文件与HTTPWebrequest?

编辑2:

我不想上传到WebDAV文件夹或类似的东西。我想模拟一个浏览器,就像你上传你的头像到一个论坛或通过一个web应用程序中的表单上传一个文件。上传到一个使用multipart/form-data的表单。

编辑:

WebClient不覆盖我的需求,所以我正在寻找一个解决方案与HTTPWebrequest。


当前回答

我知道这可能有点晚了,但我一直在寻找同样的解决方案。我从一位微软代表那里找到了以下回复

private void UploadFilesToRemoteUrl(string url, string[] files, string logpath, NameValueCollection nvc)
{

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


    HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create(url);
    httpWebRequest2.ContentType = "multipart/form-data; boundary=" +
    boundary;
    httpWebRequest2.Method = "POST";
    httpWebRequest2.KeepAlive = true;
    httpWebRequest2.Credentials = System.Net.CredentialCache.DefaultCredentials;



    Stream memStream = new System.IO.MemoryStream();
    byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");


    string formdataTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\";\r\n\r\n{1}";

    foreach(string key in nvc.Keys)
    {
        string formitem = string.Format(formdataTemplate, key, nvc[key]);
        byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
        memStream.Write(formitembytes, 0, formitembytes.Length);
    }


    memStream.Write(boundarybytes,0,boundarybytes.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++)
    {

        string header = string.Format(headerTemplate,"file"+i,files[i]);
        byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
        memStream.Write(headerbytes,0,headerbytes.Length);


        FileStream fileStream = new FileStream(files[i], FileMode.Open,
        FileAccess.Read);
        byte[] buffer = new byte[1024];

        int bytesRead = 0;

        while ( (bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0 )
        {
            memStream.Write(buffer, 0, bytesRead);
        }


        memStream.Write(boundarybytes,0,boundarybytes.Length);


        fileStream.Close();
    }

    httpWebRequest2.ContentLength = memStream.Length;
    Stream requestStream = httpWebRequest2.GetRequestStream();

    memStream.Position = 0;
    byte[] tempBuffer = new byte[memStream.Length];
    memStream.Read(tempBuffer,0,tempBuffer.Length);
    memStream.Close();
    requestStream.Write(tempBuffer,0,tempBuffer.Length );
    requestStream.Close();


    WebResponse webResponse2 = httpWebRequest2.GetResponse();

    Stream stream2 = webResponse2.GetResponseStream();
    StreamReader reader2 = new StreamReader(stream2);

    webResponse2.Close();
    httpWebRequest2 = null;
    webResponse2 = null;

}

其他回答

我最近不得不处理这个问题——另一种方法是使用WebClient是可继承的这一事实,并从那里改变底层的WebRequest:

http://msdn.microsoft.com/en-us/library/system.net.webclient.getwebrequest (VS.80) . aspx

我更喜欢c#,但如果你坚持使用VB,结果将是这样的:

Public Class BigWebClient
    Inherits WebClient
    Protected Overrides Function GetWebRequest(ByVal address As System.Uri) As System.Net.WebRequest
        Dim x As WebRequest = MyBase.GetWebRequest(address)
        x.Timeout = 60 * 60 * 1000
        Return x
    End Function
End Class

'Use BigWebClient here instead of WebClient

基于上面提供的代码,我添加了对多个文件的支持,也可以直接上传流,而不需要有本地文件。

要将文件上传到包含一些post参数的特定url,请执行以下操作:

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 } },
    });

为了进一步增强这一点,可以从给定的文件本身确定名称和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();
        }


    }
}

我想你在寻找更像WebClient的东西。

具体来说,还是()。

类似这样的代码很接近:(未测试的代码)

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();

采取以上和修改它接受一些头值,和多个文件

    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);

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;
    }
}