2010-05-08 11 views
5

chicos, antes que nada gracias por sus contribuciones, he encontrado excelentes respuestas aquí. Sin embargo, me encontré con un problema que no puedo entender y si alguien pudiera proporcionar ayuda, sería muy apreciado.Cómo simular la carga de archivos del navegador con HttpWebRequest

Estoy desarrollando esta aplicación en C# que podría cargar una imagen de la computadora al blog de usuario. Para esto estoy usig la plataforma pixelpost para fotoblogs que está escrita principalmente en PHP.

He buscado aquí y en otras páginas web, pero los ejemplos proporcionados allí no funcionaron para mí. Esto es lo que he usado en mi ejemplo: (Upload files with HTTPWebrequest (multipart/form-data)) y (http://bytes.com/topic/c-sharp/answers/268661-how-upload-file-via-c-code) Una vez que esté listo voy a hacer que esté disponible de forma gratuita en Internet y tal vez también crear un Windows versión móvil de ella, ya que soy un fan de pixelpost.

Este es el código que he utilizado:

 string formUrl = "http://localhost/pixelpost/admin/index.php?x=login"; 
     string formParams = string.Format("user={0}&password={1}", "user-String", "password-String"); 
     string cookieHeader; 
     HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(formUrl); 
     req.ContentType = "application/x-www-form-urlencoded"; 
     req.Method = "POST"; 
     req.AllowAutoRedirect = false; 
     byte[] bytes = Encoding.ASCII.GetBytes(formParams); 
     req.ContentLength = bytes.Length; 
     using (Stream os = req.GetRequestStream()) 
     { 
      os.Write(bytes, 0, bytes.Length); 
     } 
     HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); 
     cookieHeader = resp.Headers["Set-Cookie"]; 

     string pageSource; 
     using (StreamReader sr = new StreamReader(resp.GetResponseStream())) 
     { 
      pageSource = sr.ReadToEnd(); 
      Console.WriteLine(); 
     } 

     string getUrl = "http://localhost/pixelpost/admin/index.php"; 
     HttpWebRequest getRequest = (HttpWebRequest)HttpWebRequest.Create(getUrl); 
     getRequest.Headers.Add("Cookie", cookieHeader); 
     HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse(); 
     using (StreamReader sr = new StreamReader(getResponse.GetResponseStream())) 
     { 
      pageSource = sr.ReadToEnd(); 
     } 

     // end first part: login to admin panel 

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

     HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create("http://localhost/pixelpost/admin/index.php?x=save"); 
     httpWebRequest2.ContentType = "multipart/form-data; boundary=" + boundary; 
     httpWebRequest2.Method = "POST"; 
     httpWebRequest2.AllowAutoRedirect = false; 
     httpWebRequest2.KeepAlive = false; 
     httpWebRequest2.Credentials = System.Net.CredentialCache.DefaultCredentials; 
     httpWebRequest2.Headers.Add("Cookie", cookieHeader); 



     Stream memStream = new System.IO.MemoryStream(); 

     byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n"); 


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

     string formitem = string.Format(formdataTemplate, "headline", "image-name"); 
     byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); 
     memStream.Write(formitembytes, 0, formitembytes.Length); 

     memStream.Write(boundarybytes, 0, boundarybytes.Length); 


     string headerTemplate = "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: application/octet-stream\r\n\r\n"; 



     string header = string.Format(headerTemplate, "userfile", "path-to-the-local-file"); 

     byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header); 

     memStream.Write(headerbytes, 0, headerbytes.Length); 


     FileStream fileStream = new FileStream("path-to-the-local-file", FileMode.Open, FileAccess.Read); 
     byte[] buffer = new byte[1024]; 

     int bytesRead = 0; 

     while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0) 
     { 
      memStream.Write(buffer, 0, bytesRead); 

     } 

     memStream.Write(boundarybytes, 0, boundarybytes.Length); 

     fileStream.Close(); 


     httpWebRequest2.ContentLength = memStream.Length; 

     Stream requestStream = httpWebRequest2.GetRequestStream(); 

     memStream.Position = 0; 
     byte[] tempBuffer = new byte[memStream.Length]; 
     memStream.Read(tempBuffer, 0, tempBuffer.Length); 
     memStream.Close(); 
     requestStream.Write(tempBuffer, 0, tempBuffer.Length); 
     requestStream.Close(); 


     WebResponse webResponse2 = httpWebRequest2.GetResponse(); 

     Stream stream2 = webResponse2.GetResponseStream(); 
     StreamReader reader2 = new StreamReader(stream2); 


     Console.WriteLine(reader2.ReadToEnd()); 

     webResponse2.Close(); 
     httpWebRequest2 = null; 
     webResponse2 = null; 

y también aquí es el PHP: (http://dl.dropbox.com/u/3149888/index.php) y (http://dl.dropbox.com/u/3149888/new_image.php)

los campos obligatorios son titular y userfile así que no puedo entender dónde está el error, ya que el formato enviado a la derecha. Supongo que hay algo mal con la secuencia de octetos enviada al formulario. Quizás es un error estúpido que no fui capaz de rastrear, de todos modos, si pudiera ayudarme eso significaría mucho.

gracias,

+1

¿Funciona el inicio de sesión? ¿Recupera la cookie? –

+1

¿Qué no está trabajando al respecto? –

+0

Sí, el inicio de sesión funciona bien. Devuelvo la cookie y si visualizo la cadena pageSource en la consola, justo antes de "// finalizar la primera parte: iniciar sesión en el panel de administración" contiene el código HTML para el panel de administración. Para la segunda solicitud, cuando estoy enviando todos los datos del formulario y el archivo octet-stream, puedo recuperar HTML para la página "Enviar" con solo el título configurado como 'nombre-imagen' y no se carga ninguna imagen al Blog. Así que, básicamente, no puedo subir la imagen. Normalmente, si algo está mal, debería recibir un mensaje de error; en su lugar, obtengo el HTML con el conjunto de títulos. – cucicov

Respuesta

5

Así que Martin me ayudaron a salir aquí y que era capaz de hacer los cambios importantes en el código anterior con el fin de que funcione correctamente. El tipo de contenido tuvo que cambiarse a image/jpeg. También usé el tipo de imagen C# para enviar la transmisión de imágenes.

También preste atención al formato Stream, ya que no tiene que contener espacios adicionales o líneas nuevas.

aquí es la parte cambiada:

 string formUrl = "http://localhost/pixelpost/admin/index.php?x=login"; 
     string formParams = string.Format("user={0}&password={1}", "username", "password"); 
     string cookieHeader; 
     HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(formUrl); 
     req.ContentType = "application/x-www-form-urlencoded"; 
     req.Method = "POST"; 
     req.AllowAutoRedirect = false; 
     byte[] bytes = Encoding.ASCII.GetBytes(formParams); 
     req.ContentLength = bytes.Length; 
     using (Stream os = req.GetRequestStream()) 
     { 
      os.Write(bytes, 0, bytes.Length); 
     } 
     HttpWebResponse resp = (HttpWebResponse)req.GetResponse(); 
     cookieHeader = resp.Headers["Set-Cookie"]; 

     string pageSource; 
     using (StreamReader sr = new StreamReader(resp.GetResponseStream())) 
     { 
      pageSource = sr.ReadToEnd(); 
     } 

     string getUrl = "http://localhost/pixelpost/admin/index.php"; 
     HttpWebRequest getRequest = (HttpWebRequest)HttpWebRequest.Create(getUrl); 
     getRequest.Headers.Add("Cookie", cookieHeader); 
     HttpWebResponse getResponse = (HttpWebResponse)getRequest.GetResponse(); 
     using (StreamReader sr = new StreamReader(getResponse.GetResponseStream())) 
     { 
      pageSource = sr.ReadToEnd(); 
     } 


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

     HttpWebRequest httpWebRequest2 = (HttpWebRequest)WebRequest.Create("http://localhost/pixelpost/admin/index.php?x=save"); 
     httpWebRequest2.ContentType = "multipart/form-data; boundary=" + boundary; 
     httpWebRequest2.Method = "POST"; 
     httpWebRequest2.AllowAutoRedirect = false; 
     httpWebRequest2.KeepAlive = false; 
     httpWebRequest2.Credentials = System.Net.CredentialCache.DefaultCredentials; 
     httpWebRequest2.Headers.Add("Cookie", cookieHeader); 

     Stream memStream = new System.IO.MemoryStream(); 

     byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary); 


     string headerTemplate = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: image/jpeg\r\n\r\n"; 



     string header = string.Format(headerTemplate, "userfile", "Sunset.jpg"); 



     byte[] headerbytes = System.Text.Encoding.ASCII.GetBytes(header); 

     memStream.Write(headerbytes, 0, headerbytes.Length); 


     Image img = null; 
     img = Image.FromFile("C:/Documents and Settings/Dorin Cucicov/My Documents/My Pictures/Sunset.jpg", true); 
     img.Save(memStream, System.Drawing.Imaging.ImageFormat.Jpeg); 


     memStream.Write(boundarybytes, 0, boundarybytes.Length); 


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

     string formitem = string.Format(formdataTemplate, "headline", "Sunset"); 
     byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem); 
     memStream.Write(formitembytes, 0, formitembytes.Length); 

     memStream.Write(boundarybytes, 0, boundarybytes.Length); 


     httpWebRequest2.ContentLength = memStream.Length; 

     Stream requestStream = httpWebRequest2.GetRequestStream(); 

     memStream.Position = 0; 
     byte[] tempBuffer = new byte[memStream.Length]; 
     memStream.Read(tempBuffer, 0, tempBuffer.Length); 
     memStream.Close(); 
     requestStream.Write(tempBuffer, 0, tempBuffer.Length); 
     requestStream.Close(); 


     WebResponse webResponse2 = httpWebRequest2.GetResponse(); 

     Stream stream2 = webResponse2.GetResponseStream(); 
     StreamReader reader2 = new StreamReader(stream2); 


     Console.WriteLine(reader2.ReadToEnd()); 

     webResponse2.Close(); 
     httpWebRequest2 = null; 
     webResponse2 = null; 

Gracias a todos de nuevo por responder o simplemente leer.

Cuestiones relacionadas