2009-06-02 9 views
0

Hey, ich versuche gerade, eine Bilddatei mit einer Web-Anfrage, einem Speicher-Stream und einem Bild-Objekt an einen Webserver zu senden.C# Bild-Objekt in Web-Anforderung lesen

Dies ist meine aktuelle Methode zum Senden der Anfrage:

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

     Request.Method = "POST"; 
     Request.ContentType = "multipart/form-data; boundary=" + CONTENT_BOUNDARY; 
     Request.Headers.Add("Cache-Control", "no-cache"); 
     Request.KeepAlive = true; 
     Request.ContentLength = GetFormElements().Length + 
     GetFileHeader(FileName).Length + 
     FILE_TRAIL.Length + 
     ConvertImageToByteArray(image).Length; 

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

     string PostData = ASCIIEncoding.ASCII.GetString(ConvertImageToByteArray(image)); 

     StreamWriter SW = new StreamWriter(Request.GetRequestStream(), Encoding.ASCII); 
     SW.Write(PostData); 

     GetRequestResponse(); 
     Console.WriteLine(Request.HaveResponse); 
     FileStream.Close(); 
     Request = null; 

    } 

Das Problem, das ich habe ist, dass ich überhaupt keine Antwort vom Server erhalten, trotz des Stromes zu sein, was ein sein aussehen korrekte Länge (I entfernt einige Debug-Ausgaben aus dem Code oben)

Falls nötig, kann ich andere Teile meiner Klasse schreiben, aber jetzt sind hier die Schreibfunktionen:

WriteStringToStream:

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

WriteImageToSteam:

private void WriteImageToStream(System.IO.MemoryStream Stream, Image img) 
{ 
    Stream.Write(ConvertImageToByteArray(img), 0, ConvertImageToByteArray(img).Length); 
} 

ConvertImageToByteArray:

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

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

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

In ConvertImageToByteArray können Sie memStream.ToArray zurückkehren wite(); anstatt ein Array zu deklarieren und den Stream darin einzulesen. – SLaks

+0

Welcher Code ist in GetRequestResponse? – SLaks

+0

In WriteImageToStream sollten Sie ConvertImageToByteArray nicht zweimal aufrufen - es wird ziemlich langsam sein. Deklarieren Sie stattdessen ein Bytearray und lesen Sie seine Length-Eigenschaft – SLaks

Antwort

0

Problem gelöst :) ich jetzt eine Antwort haben - auch wenn es nicht das, was ich erwartet hatte ...

0

, was der Zweck der "Filestream" ist? Die Deklaration wird nicht angezeigt, Sie schreiben Daten in, dann schließen Sie sie einfach. Wolltest du es in den Anfrage-Stream schreiben und vergessen? Scheint so, als würdest du es in Request.ContentLength zählen, aber schreib es niemals in die Anfrage.

+0

, die ich in das Schreiben in den Anforderungsstream eingefügt habe, bevor Sie geantwortet haben. Ich habe sie versehentlich entfernt, als Sie sie hier posten –

+0

, aber nach der Zeile WriteStringToStream (FileStream, FILE_TRAIL); FileStream wird nur noch einmal aufgerufen - um es zu schließen. Vielleicht vermisse ich etwas. –

+0

Das ist meine Schuld, als ich einige Debug-Ausgaben für die Anzeige des Codes hier entfernt habe, nahm ich versehentlich auch den Stream-Writer heraus - ich habe ihn jetzt hier im Code ersetzt (er war immer im Code auf meinem Rechner) –

3

Sie sollten SW schließen, bevor Sie die Anfrage senden.

Anstatt das Bytearray in ASCII zu konvertieren und es dann in einen StreamWriter zu schreiben, sollten Sie das Bytearray direkt in den Anforderungsstream schreiben. (Und dann die Anfrage Strom schließen, bevor die Anfrage zu senden)

+0

Ok Ich habe das Byte-Array direkt in den Request-Stream geschrieben. Ich erhalte jetzt einen Fehler, wenn ich versuche, den Anfrage-Stream zu schließen "Die Anfrage wurde abgebrochen: Die Anfrage wurde abgebrochen." - Verwenden von Request.GetRequestStream(). Close(); - sowie ein Fehler, wenn ich versuche, den Stream-Writer zu schließen –

0
 private void GetRequestResponse() 
    { 
     if (null == FileStream) 
     { 
      System.IO.Stream stream; 
      WebResponse webResponse; 
      try 
      { 
       webResponse = Request.GetResponse(); 
      } 
      catch (WebException web) 
      { 
       webResponse = web.Response; 
      } 

      if (null != webResponse) 
      { 
       stream = webResponse.GetResponseStream(); 
       StreamReader sr = new StreamReader(stream); 
       string str; 
       Response = ""; 

       while ((str = sr.ReadLine()) != null) 
       { 
        Response += str; 
       } 
       webResponse.Close(); 
      } 
      else 
      { 
       throw new Exception("Error retrieving server response"); 
      } 
     } 
    } 

Als Reaktion auf SLaks ist die oben wird der Inhalt des GetRequestResponse. In dieser Klasse ist Response nur eine Zeichenfolge.