2009-06-05 2 views
2

Ich arbeite derzeit auf eine Datei von einer C# -Anwendung auf einen Image-Host (KalleLoad.net - mit Zustimmung des Besitzers, offensichtlich).HTTP-Web-Anfrage nicht zurück, was erwartet wird in C#

Ich habe die tatsächliche Buchung der Anfrage zu arbeiten, aber es ist nicht zurück, was ich erwartet habe. Der Besitzer der Upload-Site hat mir eine Art von API zur Verfügung gestellt, die XML mit den URLs zurückgibt, wenn ich die Daten an eine bestimmte Adresse poste. Ich kann die Daten erfolgreich posten und eine Antwort vom Server erhalten, jedoch wird einfach der Code für die Homepage anstelle des XML zurückgegeben. Ich kann nicht verstehen, warum das so ist.

Ich habe auch versucht, Daten auf einer einfachen PHP-Seite auf meinem lokalen Server zu veröffentlichen, und es gibt auch den Code für die Seite, anstatt, was ich angewiesen, die Seite auf Post zurückgeben.

Unten ist die Gesamtheit meiner aktuellen Klasse für das Senden der Daten. Ich habe auch die Header, die ich von meiner Anwendung gesendet habe, mit denen verglichen, die Firefox in der letzten halben Stunde gesendet hat, und ich kann keine wirklichen Unterschiede zwischen den Spielen erkennen (soweit ich weiß).

Jede Hilfe hier wäre fantastisch und gnädig erhalten.

Grüße, Andy Hunt

using System; 
using System.Net; 
using System.Text; 
using System.IO; 
using System.Collections; 
using System.Collections.Generic; 
using System.Drawing; 

namespace Skimpt_3._0 
{ 
    class PostFile 
    { 
     private Hashtable FormElements; 
     private HttpWebRequest Request; 
     private MemoryStream FileStream; 

     private string CONTENT_BOUNDARY = "---------------------------265001916915724"; 

     public string ContentMIMEType; 
     public string FormURL; 
     public string FileName; 
     public string Response; 
     public string FileBoxName; 

     //private int BufferSize; 

     public PostFile(string Url, string strFileName) 
     { 
      FormElements = new Hashtable(); 
      FormURL = Url; 
      Request = (HttpWebRequest)WebRequest.Create(Url); 
      //BufferSize = 10240; 
      FileStream = new MemoryStream(); 
      FileName = strFileName; 
     } 

     public void Send(Image image) 
     { 
      //Assign the request here too, just in case 
      Request = (HttpWebRequest)WebRequest.Create(FormURL); 

      Request.Method = "POST"; 
      Request.AllowWriteStreamBuffering = true; 
      Request.ProtocolVersion = HttpVersion.Version11; 
      Request.Headers.Add("Cache-Control", "no-cache"); 
      Request.KeepAlive = true; 
      Request.ContentType = "multipart/form-data; boundary=---------------------------265001916915724"; 
      StartFileStream(FileStream); 

      //Must be done in this order for stream to write properly: 
      //---- 
      //Form elements 
      //File header 
      //Image 
      //File trailer 
      //---- 
      WriteStringToStream(FileStream, GetFormElements()); 
      WriteImageToStream(FileStream, image, FileName); 

      CloseStream(FileStream); 


      byte[] FileByteArray = FileStream.ToArray(); 

      Request.ContentLength = FileByteArray.Length; 

      Stream PostingStream = Request.GetRequestStream(); 
      PostingStream.Write(FileByteArray, 0, FileByteArray.Length); 

      WebResponse resp = (HttpWebResponse)Request.GetResponse(); 

      StreamReader SR = new StreamReader(resp.GetResponseStream()); 

      PostingStream.Close(); 

      FileStream.Close(); 
      Request.GetRequestStream().Close(); 
      Response = SR.ReadToEnd(); 
      Request = null; 
     } 

     private void CloseStream(MemoryStream FileStream) 
     { 
      byte[] BytesToWrite = Encoding.ASCII.GetBytes(CONTENT_BOUNDARY); 
      FileStream.Write(BytesToWrite, 0, BytesToWrite.Length); 
     } 

     private void StartFileStream(MemoryStream FileStream) 
     { 
      // \r\n = new line 
      string str = "POST " + FormURL +"Content-Type: multipart/form-data; boundary="+CONTENT_BOUNDARY+" \r\n \r\n" + CONTENT_BOUNDARY; 
      byte[] BytesToWrite = Encoding.ASCII.GetBytes(str); 
      FileStream.Write(BytesToWrite, 0, BytesToWrite.Length); 
     } 

     private Byte[] ConvertImageToByteArray(Image img) 
     { 
      //Method taken from http://www.csharp-station.com/Articles/Thumbnails.aspx and adapted 
      MemoryStream memStream = new MemoryStream(); 
      img.Save(memStream, System.Drawing.Imaging.ImageFormat.Png); 

      byte[] byteArray = new Byte[memStream.Length]; 

      memStream.Position = 0; 
      memStream.Read(byteArray, 0, (int)memStream.Length); 
      return byteArray; 
     } 

     public void AddFormElement(string ElementName, string ElementValue) 
     { 
      FormElements[ElementName] = ElementValue; 
     } 

     private string GetFormElements() 
     { 
      string str = ""; 
      IDictionaryEnumerator myEnumerator = FormElements.GetEnumerator(); 
      while (myEnumerator.MoveNext()) 
      { 
       str += CONTENT_BOUNDARY + "\r\n" + 
        "Content-Disposition: form-data; name=" + myEnumerator.Key + 
        "\r\n\r\n" + 
        myEnumerator.Value +"\r\n"; 
      } 
      return str; 
     } 


     private void WriteStringToStream(System.IO.MemoryStream stream, string String) 
     { 
      byte[] PostData = System.Text.Encoding.ASCII.GetBytes(String); 
      stream.Write(PostData, 0, PostData.Length); 
     } 

     private void WriteImageToStream(System.IO.MemoryStream Stream, Image img, string FileName) 
     { 
      byte[] ByteArray = ConvertImageToByteArray(img); 
      string head = CONTENT_BOUNDARY + "\r\n" + 
          "Content-Disposition: form-data; name=\"" + FileBoxName + "\"; filename=\"" + FileName + "\"\r\n" + 
          "Content-Type: " + ContentMIMEType + "\r\n\r\n"; 
      byte[] header = Encoding.ASCII.GetBytes(head); 

      Stream.Write(header, 0, header.Length); 

      Stream.Write(ByteArray, 0, ByteArray.Length); 
     } 
    } 
} 
+0

Ich lese gerade Ihren Code durch, und ich habe etwas bemerkt, das nicht mit der Webantwort zusammenhängt. Wenn Sie das Bild in ein Byte [] konvertieren möchten, nachdem Sie img.Save (....) ausgeführt haben, können Sie einfach memStream.ToArray() zurückgeben, wodurch das Byte [] Ihres Bildes zurückgegeben wird. – Aaron

+0

Danke, das habe ich jetzt behoben. Ich werde mich nicht darum kümmern, es im obigen Code zu aktualisieren, da es nicht wirklich aktualisiert werden muss. –

Antwort

1

Von dem, was ich die POST-Anforderung kann sagen, dass Sie einreichen nicht korrekt gebildet wird. Ich glaube nicht, dass der Server versteht, wie er die Daten interpretiert, die Sie senden (daher erhalten Sie nicht die Antwort, die Sie erwarten).

Was für eine Anforderung POST sollte wie

POST /_layouts/Upload.aspx HTTP/1.1 
Content-Type: multipart/form-data; boundary=---------------------------7d9192265018e 
Host: 127.0.0.1:25540 
Content-Length: 3573 
Connection: Keep-Alive 
---------------------------7d9192265018e 
-----------------------------7d9192265018e 
Content-Disposition: form-data; name="uploadFile"; filename="C:\Temp\TestDocument.txt" 
Content-Type: text/plain 

blah 
-----------------------------7d9192265018e-- 

aussehen zu laden (Hinweis: der Content-Length-Wert über falsch ist. Ich ein paar Sachen aus Gründen der Kürze entfernt)


Welcher POST-Request, den Sie generieren, sieht wie folgt aus:

POST /WebSite1/Default.aspx HTTP/1.1 
Cache-Control: no-cache 
Content-Type: multipart/form-data; boundary=---------------------------265001916915724 
Host: 127.0.0.1:25540 
Content-Length: 8626 
Expect: 100-continue 
Connection: Keep-Alive 

POST http://ipv4.fiddler:25540/WebSite1/Default.aspxContent-Type: multipart/form-data; boundary=-----------------------------265001916915724 

-----------------------------265001916915724-----------------------------265001916915724 
Content-Disposition: form-data; name=""; filename="Test.png" 
Content-Type: 

?PNG 
-----------------------------265001916915724-- 

(Hinweis: Ich habe die PNG-Datei Daten weggelassen habe, dass ich mit getestet)


Durch Vergleich der beiden, kann ich die folgenden Probleme sehen:

  • Die Grenze wird falsch verwendet. Sie verwenden an allen Stellen dieselbe Zeichenfolge. Nach dem Setzen eines Randwertes (Beispiel: boundary=aaaBBBcccDDDeee) mit dem Header Content-Type verwenden Sie die Grenze mit dem Präfix "-" (Beispiel: - boundary=aaaBBBcccDDDeee), um jeden Teil Ihrer mehrteiligen Formularübertragung zu begrenzen. Die letzte Grenze markiert das Ende der mehrteiligen Daten und muss mit einem "-" - Präfix und Suffix (Beispiel: --boundary=aaaBBBcccDDDeee--. Siehe RFC 1341 (MIME): 7 für weitere Informationen.
  • Es gibt eine seltsame Expect: 100-continue Header in Ihrer Anfrage. Das sieht B. ein Problem mit der .NET HttpWebRequest-Klasse und kann deaktiviert werden. Weitere Informationen finden Sie unter HttpWebRequest and the Expect: 100-continue Header Problem.
  • Die StartFileStream-Methode versucht, einen Header-Wert zu schreiben, aber Sie geben die Ausgabe in den Anfragetext ein. Es schreibt auch Header falsch. Ich denke, das sollte ganz weggelassen werden (es sieht so aus, als ob es sich von einem anderen Upload-Code angepasst hätte).
  • Das Feld ContentMIMEType sollte auf den MIME-Typ des Bildes eingestellt sein, das Sie hochladen. Es ist überhaupt nicht festgelegt, daher ist der Inhaltstyp des hochgeladenen Bilds leer.
  • Dito für das Feld FileBoxName.

Wie das

debuggen Sie Fiddler die Anforderung zu sehen, benutzen können, die Ihre zu senden. Um es einzurichten, müssen Sie in der Lage sein, eine Anfrage an einen Webserver zu senden. Sie sollten in der Lage sein, es auszuführen und jede Anfrage, die Sie senden möchten, abzufangen.

Puh! Das war lang. Viel Glück und ich hoffe das hilft!

+0

Danke für die Antwort. Ich werde mir all die Dinge ansehen, die du vorgeschlagen hast. Wie für die Variablen ContentMIMEType und FileBoxName werden sie außerhalb der Klasse festgelegt. IE Instanz.ContentMIMEType = "image/png"; –

+0

Das hat super funktioniert, danke. Es stellte sich heraus, dass ich immer nur die doppelten Striche ("-") vor den Inhaltsgrenzen einfügen musste. Nochmals vielen Dank. Es nervt mich seit Tagen. –

+0

Ok, das funktioniert jetzt aber nur teilweise. Aus irgendeinem Grund wird hochgeladen, aber nur teilweise. Es sendet den MIME-Typ nicht richtig oder die Größe oder eine dieser Eigenschaften. Irgendwelche Ideen? –

Verwandte Themen