2009-07-30 13 views
14

Jaki jest najłatwiejszy sposób przesłania żądania HTTP POST z typem treści wieloczęściowych/danych formularza z C#? Musi istnieć lepszy sposób niż budowanie mojej własnej prośby.Jak wysłać żądanie HTTP POST dla wielu formatów/formularzy z C#

Powód pytam jest do przesyłania zdjęć do serwisu Flickr przy użyciu tego API:

http://www.flickr.com/services/api/upload.api.html

+1

Zajmowałem się głównie przeglądaniem HttpWebRequest, ale wszystkie zasoby znalezione w Internecie wyjaśniają, jak ręcznie skompilować żądanie. Oto jeden z wielu podobnych przykładów, które znalazłem: http://social.msdn.microsoft.com/Forums/en-US/netfxnetcom/thread/03efc98c-68e2-410c-bf25-d5facacbd920 –

+0

To pytanie zawiera odpowiedź rozwiązuje twój problem z wysyłaniem wieloczęściowych/formularzy danych przy użyciu WebRequest. To dobrze działa. http://stackoverflow.com/questions/219827/multipart-forms-from-c-client – Marek

Odpowiedz

1

Przede wszystkim, nie ma nic złego w czystej ręcznego wykonania poleceń HTTP z wykorzystaniem .NET Framework. Należy pamiętać, że jest to framework i ma być dość ogólny.

Po drugie, myślę, że możesz spróbować wyszukać implementację przeglądarki w .Net. Widziałem this one, może to dotyczy problemu, o który pytałeś. Lub po prostu wyszukaj "C# http put get post request". Jeden z wyników prowadzi do niewolnej biblioteki, która może być pomocna (Chilkat Http)

Jeśli zdarzy ci się napisać własną strukturę poleceń HTTP na .Net - myślę, że wszyscy możemy się nią cieszyć, jeśli udostępnisz to :-)

+0

Niestety, właśnie to musiałem zrobić. –

1

Klasa System.Net.WebClient może być tym, czego szukasz. Sprawdź dokumentację dla WebClient.UploadFile, powinna ona umożliwić przesłanie pliku do określonego zasobu przez jeden z przeciążeń UploadFile. Myślę, że jest to metoda szukasz użyć aby umieścić dane ...

Może być używany jak .... Uwaga To jest tylko przykładowy kod nie testowane ...

WebClient WebClient = new WebClient();

webClient.UploadFile ("http://www.url.com/ReceiveUploadedFile.aspx", "POST", @ "c: \ mójplik.txt");

Oto numer referencyjny MSDN, jeśli jesteś zainteresowany.

http://msdn.microsoft.com/en-us/library/system.net.webclient.uploadfile.aspx

Nadzieja to pomaga.

+1

To by działało, gdybym tylko załadował plik. Jednak wraz z nim muszę dołączyć kilka innych zmiennych formularza. –

2

Odniosłem sukces z kodem opublikowanym pod numerem aspnetupload.com. W końcu stworzyłem własną wersję biblioteki UploadHelper, która jest kompatybilna z Compact Framework. Działa dobrze, wydaje się, że robi dokładnie to, czego potrzebujesz.

+0

Powinienem dodać, że "make my own version" == spróbuj skompilować bibliotekę w projekcie Compact Framework, zobacz, co jest uszkodzone, użyj innego obiektu zgodnego z CF lub segmentu kodu, aby zrobić to samo, powtórz. Byłem mile zaskoczony tym, jak prosty był ten proces. –

5

Jeśli używasz .NET 4.5 użyj:

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

W przeciwnym razie w oparciu o odpowiedź Ryana, ściągnąłem bibliotekę i manipulowane go trochę.

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

Pierwsza funkcja nie działa. Czym jest "a"? – user656822

+0

Ups, powinno być requestParameters. Naprawiony. –

+0

Wiem, że jest stary, ale nie działał dla mnie, dopóki nie zaimportowałem moich treści ręcznie, jak tutaj -> http://stackoverflow.com/a/12034014/885338 – Arikael

2

nie próbowałem ten sam, ale nie wydaje się być wbudowany w sposób w C# na to (choć nie bardzo wiadomo, jeden najwyraźniej ...):

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

Wypróbuj i daj mi znać, jak to działa.

Pozdrawiam!

Powiązane problemy