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

编辑2:

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

编辑:

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


当前回答

不确定这是否张贴之前,但我得到了这个工作与WebClient。我读了WebClient的文档。他们提出的一个关键点是

如果BaseAddress属性不是空字符串("")和address 不包含绝对URI,地址必须是相对URI那 与BaseAddress结合形成所请求的URI的绝对URI 数据。如果QueryString属性不是空字符串,那么它就是空字符串 附于地址。

我所做的就是wc。querystring。添加(“源”,generatedImage)来添加不同的查询参数,以某种方式将属性名称与我上传的图像匹配。希望能有所帮助

    public void postImageToFacebook(string generatedImage, string fbGraphUrl)
    {
        WebClient wc = new WebClient();
        byte[] bytes = System.IO.File.ReadAllBytes(generatedImage);

        wc.QueryString.Add("source", generatedImage);
        wc.QueryString.Add("message", "helloworld");

        wc.UploadFile(fbGraphUrl, generatedImage);

        wc.Dispose();

    }

其他回答

修改了@CristianRomanescu代码,以使用内存流,接受文件作为字节数组,允许空nvc,返回请求响应和使用授权头。使用Web Api 2测试代码。

private string HttpUploadFile(string url, byte[] file, string fileName, string paramName, string contentType, NameValueCollection nvc, string authorizationHeader)
{
    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.Headers.Add("Authorization", authorizationHeader);
    wr.KeepAlive = true;

    Stream rs = wr.GetRequestStream();

    string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
    if (nvc != null)
    {
        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, fileName, contentType);
    byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
    rs.Write(headerbytes, 0, headerbytes.Length);

    rs.Write(file, 0, file.Length);

    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);
        var response = reader2.ReadToEnd();
        return response;
    }
    catch (Exception ex)
    {
        if (wresp != null)
        {
            wresp.Close();
            wresp = null;
        }
        return null;
    }
    finally
    {
        wr = null;
    }
}

Testcode:

[HttpPost]
[Route("postformdata")]
public IHttpActionResult PostFormData()
{
    // Check if the request contains multipart/form-data.
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }

    var provider = new MultipartMemoryStreamProvider();

    try
    {
        // Read the form data.
        var result = Request.Content.ReadAsMultipartAsync(provider).Result;
        string response = "";
        // This illustrates how to get the file names.
        foreach (var file in provider.Contents)
        {
            var fileName = file.Headers.ContentDisposition.FileName.Trim('\"');
            var buffer =  file.ReadAsByteArrayAsync().Result;
            response = HttpUploadFile("https://localhost/api/v1/createfromfile", buffer, fileName, "file", "application/pdf", null, "AuthorizationKey");
        }
        return Ok(response);
    }
    catch (System.Exception e)
    {
        return InternalServerError();
    }
}

客户端使用转换文件到ToBase64String,使用Xml发布后 到服务器调用,这个服务器使用File.WriteAllBytes(path,Convert.FromBase64String(dataFile_Client_sent))。

好幸运!

我一直在找这样的东西,在: 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();
    }
}

我永远不能让例子正常工作,我总是收到一个500错误时,把它发送到服务器。

然而,我在这个url中遇到了一个非常优雅的方法

它很容易扩展,显然可以处理二进制文件和XML。

你可以用类似的方法来称呼它

class Program
{
    public static string gsaFeedURL = "http://yourGSA.domain.com:19900/xmlfeed";

    static void Main()
    {
        try
        {
            postWebData();
        }
        catch (Exception ex)
        {
        }
    }

    // new one I made from C# web service
    public static void postWebData()
    {
        StringDictionary dictionary = new StringDictionary();
        UploadSpec uploadSpecs = new UploadSpec();
        UTF8Encoding encoding = new UTF8Encoding();
        byte[] bytes;
        Uri gsaURI = new Uri(gsaFeedURL);  // Create new URI to GSA feeder gate
        string sourceURL = @"C:\FeedFile.xml"; // Location of the XML feed file
        // Two parameters to send
        string feedtype = "full";
        string datasource = "test";            

        try
        {
            // Add the parameter values to the dictionary
            dictionary.Add("feedtype", feedtype);
            dictionary.Add("datasource", datasource);

            // Load the feed file created and get its bytes
            XmlDocument xml = new XmlDocument();
            xml.Load(sourceURL);
            bytes = Encoding.UTF8.GetBytes(xml.OuterXml);

            // Add data to upload specs
            uploadSpecs.Contents = bytes;
            uploadSpecs.FileName = sourceURL;
            uploadSpecs.FieldName = "data";

            // Post the data
            if ((int)HttpUpload.Upload(gsaURI, dictionary, uploadSpecs).StatusCode == 200)
            {
                Console.WriteLine("Successful.");
            }
            else
            {
                // GSA POST not successful
                Console.WriteLine("Failure.");
            }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }
}

查看MyToolkit库:

var request = new HttpPostRequest("http://www.server.com");
request.Data.Add("name", "value"); // POST data
request.Files.Add(new HttpPostFile("name", "file.jpg", "path/to/file.jpg")); 

await Http.PostAsync(request, OnRequestFinished);

http://mytoolkit.codeplex.com/wikipage?title=Http