2009-07-15 48 views
65

Tôi đã tìm kiếm và đọc xung quanh điều đó và không thể làm bất cứ điều gì thực sự hữu ích.Gửi một tập tin qua HTTP POST với C#

Tôi đang viết một ứng dụng nhỏ C# cho phép người dùng gửi tệp tới máy chủ web chứ không phải bằng FTP, mà bằng HTTP bằng POST. Hãy nghĩ về nó như một biểu mẫu web nhưng chạy trên một ứng dụng cửa sổ.

Tôi có HttpWebRequest tôi đối tượng được tạo ra sử dụng một cái gì đó như thế này

HttpWebRequest req = WebRequest.Create(uri) as HttpWebRequest 

và cũng đặt Method, ContentTypeContentLength tài sản. Nhưng đó là xa tôi có thể đi.

Đây là mảnh của tôi mã:

HttpWebRequest req = WebRequest.Create(uri) as HttpWebRequest; 
req.KeepAlive = false; 
req.Method = "POST"; 
req.Credentials = new NetworkCredential(user.UserName, user.UserPassword); 
req.PreAuthenticate = true; 
req.ContentType = file.ContentType; 
req.ContentLength = file.Length; 
HttpWebResponse response = null; 

try 
{ 
    response = req.GetResponse() as HttpWebResponse; 
} 
catch (Exception e) 
{ 
} 

Vì vậy, câu hỏi của tôi về cơ bản là làm thế nào tôi có thể gửi một fie (file văn bản, hình ảnh, âm thanh, vv) với C# thông qua HTTP POST.

Cảm ơn!

+0

Vui lòng kiểm tra http://stackoverflow.com/questions/15738847/sending-files-using-http-post-in-c-sharp/15739707#15739707 – Sudha

Trả lời

79

Sử dụng .NET 4.5 (hoặc .NET 4.0 bằng cách thêm gói Microsoft.Net.Http từ NuGet) có một cách dễ dàng hơn để mô phỏng các yêu cầu biểu mẫu. Dưới đây là một ví dụ:

private System.IO.Stream Upload(string actionUrl, string paramString, Stream paramFileStream, byte [] paramFileBytes) 
{ 
    HttpContent stringContent = new StringContent(paramString); 
    HttpContent fileStreamContent = new StreamContent(paramFileStream); 
    HttpContent bytesContent = new ByteArrayContent(paramFileBytes); 
    using (var client = new HttpClient()) 
    using (var formData = new MultipartFormDataContent()) 
    { 
     formData.Add(stringContent, "param1", "param1"); 
     formData.Add(fileStreamContent, "file1", "file1"); 
     formData.Add(bytesContent, "file2", "file2"); 
     var response = client.PostAsync(actionUrl, formData).Result; 
     if (!response.IsSuccessStatusCode) 
     { 
      return null; 
     } 
     return response.Content.ReadAsStreamAsync().Result; 
    } 
} 
+3

Tôi thích câu trả lời và ví dụ này. Tương tự nhất với việc gửi biểu mẫu HTML. – jocull

+0

Tôi cần xóa tham số thứ 3 trong 'formData.Add()' khi nội dung thuộc loại 'StringContent', để kịch bản lệnh máy chủ nhận biết được các trường bài đăng. – dAngelov

+0

Nếu có thể, có thể cho thấy một ví dụ đơn giản về cách gọi phương thức này? – Jacobr365

41

Để gửi các tập tin thô chỉ:

using(WebClient client = new WebClient()) { 
    client.UploadFile(address, filePath); 
} 

Nếu bạn muốn bắt chước một hình thức trình duyệt với một <input type="file"/>, thì đó là khó khăn hơn. Xem this answer để biết câu trả lời nhiều phần/biểu mẫu.

+0

(tất nhiên bạn có thể thêm tiêu đề/thông tin xác thực/v.v. như bình thường) –

+1

Cảm ơn, tôi đã sử dụng nó với một cái gì đó đơn giản và tôi đã không làm việc. Bây giờ, như bạn nói, tôi cần phải mô phỏng một tập tin đầu vào trình duyệt, đôi khi như thế này . – gabitoju

+1

Tôi đã sử dụng mã ở trên và có lỗi như: Ngoại lệ đối số đã được giải mã bởi mã người dùng: {"Định dạng URI không được hỗ trợ."}. Tôi có thể làm cái này như thế nào? void Page_Load được bảo vệ (người gửi đối tượng, EventArgs e) { địa chỉ chuỗi = "http: www.testproject.com/SavedFiles"; filepath chuỗi = @ "D: \ test \ FileOperations \ testfile.txt"; sử dụng (WebClient client = new WebClient()) { khách hàng.UploadFile (địa chỉ, filepath); } } – Sudha

4

Bạn cần phải viết tập tin của bạn lên luồng yêu cầu:

using (var reqStream = req.GetRequestStream()) 
{  
    reqStream.Write(...) // write the bytes of the file 
} 
4

tôi đã có cùng một vấn đề và đoạn mã sau này đã trả lời một cách hoàn hảo tại vấn đề này:

//Identificate separator 
string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); 
//Encoding 
byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); 

//Creation and specification of the request 
HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url); //sVal is id for the webService 
wr.ContentType = "multipart/form-data; boundary=" + boundary; 
wr.Method = "POST"; 
wr.KeepAlive = true; 
wr.Credentials = System.Net.CredentialCache.DefaultCredentials; 

string sAuthorization = "login:password";//AUTHENTIFICATION BEGIN 
byte[] toEncodeAsBytes = System.Text.ASCIIEncoding.ASCII.GetBytes(sAuthorization); 
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes); 
wr.Headers.Add("Authorization: Basic " + returnValue); //AUTHENTIFICATION END 
Stream rs = wr.GetRequestStream(); 


string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; //For the POST's format 

//Writting of the file 
rs.Write(boundarybytes, 0, boundarybytes.Length); 
byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(Server.MapPath("questions.pdf")); 
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, "file", "questions.pdf", contentType); 
byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); 
rs.Write(headerbytes, 0, headerbytes.Length); 

FileStream fileStream = new FileStream(Server.MapPath("questions.pdf"), 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(); 
rs = null; 

WebResponse wresp = null; 
try 
{ 
    //Get the response 
    wresp = wr.GetResponse(); 
    Stream stream2 = wresp.GetResponseStream(); 
    StreamReader reader2 = new StreamReader(stream2); 
    string responseData = reader2.ReadToEnd(); 
} 
catch (Exception ex) 
{ 
    string s = ex.Message; 
} 
finally 
{ 
    if (wresp != null) 
    { 
     wresp.Close(); 
     wresp = null; 
    } 
    wr = null; 
} 
0

Để gửi file kể từ mảng byte:

private static string UploadFilesToRemoteUrl(string url, IList<byte[]> files, NameValueCollection nvc) { 

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

     var request = (HttpWebRequest) WebRequest.Create(url); 
     request.ContentType = "multipart/form-data; boundary=" + boundary; 
     request.Method = "POST"; 
     request.KeepAlive = true; 
     var postQueue = new ByteArrayCustomQueue(); 

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

     foreach (string key in nvc.Keys) { 
      var formitem = string.Format(formdataTemplate, key, nvc[key]); 
      var formitembytes = Encoding.UTF8.GetBytes(formitem); 
      postQueue.Write(formitembytes); 
     } 

     var headerTemplate = "\r\n--" + boundary + "\r\n" + 
      "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\n" + 
      "Content-Type: application/zip\r\n\r\n"; 

     var i = 0; 
     foreach (var file in files) { 
      var header = string.Format(headerTemplate, "file" + i, "file" + i + ".zip"); 
      var headerbytes = Encoding.UTF8.GetBytes(header); 
      postQueue.Write(headerbytes); 
      postQueue.Write(file); 
      i++; 
     } 

     postQueue.Write(Encoding.UTF8.GetBytes("\r\n--" + boundary + "--")); 

     request.ContentLength = postQueue.Length; 

     using (var requestStream = request.GetRequestStream()) { 
      postQueue.CopyToStream(requestStream); 
      requestStream.Close(); 
     } 

     var webResponse2 = request.GetResponse(); 

     using (var stream2 = webResponse2.GetResponseStream()) 
     using (var reader2 = new StreamReader(stream2)) { 

      var res = reader2.ReadToEnd(); 
      webResponse2.Close(); 
      return res; 
     } 
    } 

public class ByteArrayCustomQueue { 

    private LinkedList<byte[]> arrays = new LinkedList<byte[]>(); 

    /// <summary> 
    /// Writes the specified data. 
    /// </summary> 
    /// <param name="data">The data.</param> 
    public void Write(byte[] data) { 
     arrays.AddLast(data); 
    } 

    /// <summary> 
    /// Gets the length. 
    /// </summary> 
    /// <value> 
    /// The length. 
    /// </value> 
    public int Length { get { return arrays.Sum(x => x.Length); } } 

    /// <summary> 
    /// Copies to stream. 
    /// </summary> 
    /// <param name="requestStream">The request stream.</param> 
    /// <exception cref="System.NotImplementedException"></exception> 
    public void CopyToStream(Stream requestStream) { 
     foreach (var array in arrays) { 
      requestStream.Write(array, 0, array.Length); 
     } 
    } 
} 
5

Đối với tôi client.UploadFile vẫn quấn nội dung trong một yêu cầu nhiều phần dữ liệu vì vậy tôi đã làm điều đó như thế này:

using (WebClient client = new WebClient()) 
{ 
    client.Headers.Add("Content-Type", "application/octet-stream"); 
    using (Stream fileStream = File.OpenRead(filePath)) 
    using (Stream requestStream = client.OpenWrite(new Uri(fileUploadUrl), "POST")) 
    { 
     fileStream.CopyTo(requestStream); 
    } 
} 
0
 public string SendFile(string filePath) 
      { 
       WebResponse response = null; 
       try 
       { 
        string sWebAddress = "Https://www.address.com"; 

        string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x"); 
        byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); 
        HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(sWebAddress); 
        wr.ContentType = "multipart/form-data; boundary=" + boundary; 
        wr.Method = "POST"; 
        wr.KeepAlive = true; 
        wr.Credentials = System.Net.CredentialCache.DefaultCredentials; 
        Stream stream = wr.GetRequestStream(); 
        string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}"; 

        stream.Write(boundarybytes, 0, boundarybytes.Length); 
        byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(filePath); 
        stream.Write(formitembytes, 0, formitembytes.Length); 
        stream.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, "file", Path.GetFileName(filePath), Path.GetExtension(filePath)); 
        byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); 
        stream.Write(headerbytes, 0, headerbytes.Length); 

        FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read); 
        byte[] buffer = new byte[4096]; 
        int bytesRead = 0; 
        while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) 
         stream.Write(buffer, 0, bytesRead); 
        fileStream.Close(); 

        byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n"); 
        stream.Write(trailer, 0, trailer.Length); 
        stream.Close(); 

        response = wr.GetResponse(); 
        Stream responseStream = response.GetResponseStream(); 
        StreamReader streamReader = new StreamReader(responseStream); 
        string responseData = streamReader.ReadToEnd(); 
        return responseData; 
       } 
       catch (Exception ex) 
       { 
        return ex.Message; 
       } 
       finally 
       { 
        if (response != null) 
         response.Close(); 
       } 
      } 
Các vấn đề liên quan