Foros del Web » Programación para mayores de 30 ;) » .NET »

POST en vb.net

Estas en el tema de POST en vb.net en el foro de .NET en Foros del Web. Necesito crear una aplicacion que realice un POST a un formulario echo en php para subir un archivo, mas especificamente una imagen, pero no encuentro ...
  #1 (permalink)  
Antiguo 11/10/2009, 17:18
Avatar de seinkraft  
Fecha de Ingreso: diciembre-2007
Mensajes: 119
Antigüedad: 16 años, 4 meses
Puntos: 1
POST en vb.net

Necesito crear una aplicacion que realice un POST a un formulario echo en php para subir un archivo, mas especificamente una imagen, pero no encuentro la forma de hacerlo.

Mire por todos lados en varios foros pero no eh podido hacer funcionar los ejemplos para ese tipo de funcion.

Alguien me puede dar una mano con ello o algun ejemplo que sirva?
  #2 (permalink)  
Antiguo 11/10/2009, 17:56
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: POST en vb.net

Hay mucho en la web, sólo tienes que buscar en Google y no tener miedo del inglés:
Working with HttpWebRequest and HttpWebResponse in ASP.NET
How to use HttpWebRequest to send POST request to another web server?
How to use HttpWebRequest and HttpWebResponse in .NET

En definitiva, tienes que estudiar el funcionamiento de la clase HttpWebRequest
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
  #3 (permalink)  
Antiguo 12/10/2009, 06:08
Avatar de seinkraft  
Fecha de Ingreso: diciembre-2007
Mensajes: 119
Antigüedad: 16 años, 4 meses
Puntos: 1
Respuesta: POST en vb.net

Gracias por la respuesta.

Tambien econtre estos ejemplos y para mi son oro puro por eso quise compartir el link.

http://developer.yahoo.com/dotnet/howto-rest_vb.html
  #4 (permalink)  
Antiguo 12/10/2009, 08:54
Avatar de seinkraft  
Fecha de Ingreso: diciembre-2007
Mensajes: 119
Antigüedad: 16 años, 4 meses
Puntos: 1
Respuesta: POST en vb.net

Bueno por el momento logre esto:

Código vb:
Ver original
  1. Private Sub btnUpload_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnUpload.Click
  2.         Dim request As HttpWebRequest
  3.         Dim response As HttpWebResponse = Nothing
  4.         Dim reader As StreamReader
  5.         Dim address As Uri
  6.         Dim data As StringBuilder
  7.         Dim byteData() As Byte
  8.         Dim postStream As Stream = Nothing
  9.  
  10.         Dim username As String
  11.         Dim password As String
  12.         Dim file_location As String
  13.         Dim tags As String
  14.         Dim source As String
  15.         Dim md5 As String
  16.  
  17.         address = New Uri("http://localhost/api/add_image")
  18.  
  19.         ' Create the web request  
  20.        request = DirectCast(WebRequest.Create(address), HttpWebRequest)
  21.  
  22.         ' Set type to POST  
  23.        request.Method = "POST"
  24.         request.ContentType = "multipart/form-data"
  25.  
  26.         ' Create the data we want to send
  27.        username = "user"
  28.         password = "userpass"
  29.         file_location = txtFile.Text
  30.         tags = "coco nu_se"
  31.         source = "http://www.seinkraft.info"
  32.         md5 = "2ef87d61eb6c5d318760db51828d8d00"
  33.  
  34.         data = New StringBuilder()
  35.         data.Append("login=" + username)
  36.         data.Append("&password=" + password)
  37.         data.Append("&file=" + file_location)
  38.         data.Append("&md5=" + md5)
  39.         data.Append("&tags=" + tags)
  40.         data.Append("&source=" + source)
  41.  
  42.         TextBox1.Text = data.ToString
  43.  
  44.         ' Create a byte array of the data we want to send  
  45.        byteData = UTF8Encoding.UTF8.GetBytes(data.ToString())
  46.  
  47.         ' Set the content length in the request headers  
  48.        request.ContentLength = byteData.Length
  49.  
  50.         ' Write data  
  51.        Try
  52.             postStream = request.GetRequestStream()
  53.             postStream.Write(byteData, 0, byteData.Length)
  54.         Finally
  55.             If Not postStream Is Nothing Then postStream.Close()
  56.         End Try
  57.  
  58.         Try
  59.             ' Get response  
  60.            response = DirectCast(request.GetResponse(), HttpWebResponse)
  61.  
  62.             ' Get the response stream into a reader  
  63.            reader = New StreamReader(response.GetResponseStream())
  64.  
  65.             ' Console application output  
  66.            TextBox2.Text = reader.ReadToEnd()
  67.         Finally
  68.             If Not response Is Nothing Then response.Close()
  69.         End Try
  70.     End Sub

Y los parametros de la api son:
Parameters
* login: login
* password: password
* file: file as a multipart form
* source: source url
* tags: list of tags as a string, delimited by whitespace
* md5: MD5 hash of upload in hexadecimal format

Lo que no se es como hacer la parte del file (ahora esta echa asi nomas). No se como enviarlo como multipart

Alguien me puede ayudar con ello?

Última edición por seinkraft; 12/10/2009 a las 09:02
  #5 (permalink)  
Antiguo 02/02/2010, 13:24
 
Fecha de Ingreso: febrero-2010
Mensajes: 3
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: POST en vb.net

Hola.

Recorriendo varios foros encontré este problema, voy a intentar ser lo más claro posible. El problema principal es que no hay muchos ejemplos y los que hay son poco claro.

Para abordar este tema hay que tener en cuenta las necesidades de cada aplicación y la configuración del servidor al que vamos a enviar el archivo

De la aplicación tener en cuenta
  • Si se envía datos de cadena solamente
  • Si se envía archivo/s
  • Utiliza buffer de escritura

Del servidor tener en cuanta
  • Que protocolo utiliza
    • Si es a través de HTTPS (SSL) requiere que revisemos el certificado del servidor
  • Que tipo de autenticación utiliza
    • Anónima
    • Integrada
      • Debemos pasarle las credenciales de conexión o indicarle que utilice las por defecto
    • Básica
      • Indicarle en el head del post el usuario y la contraseña

Certificado del servidor

Cuando la conexión se realiza a través de HTTPS el objeto HttpWebRequest va a requerir una función que valide el certicado del servidor.
¿Como se hace?
1) Crear la función que analiza el certificado
Código vb:
Ver original
  1. Private Function ValidateCertificate(ByVal sender As Object, ByVal      certificate As X509Certificate, ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
  2.         Dim resultado As Boolean
  3.         resultado = True
  4.         '
  5.        ' Analizar el certificado y devolver true o false según sea el caso
  6.        '
  7.        Return resultado
  8.     End Function
2) Asignar la misma al “ServicePointManager”

Código vb:
Ver original
  1. ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateCertificate)


Autenticación
Según el tipo de autenticación requerida por el servidor utilizaremos alguno de los siguiente códigos, hay otras formas de asignar las credenciales, les dejo las que me parecen las más simples

Autenticación Anónima
Podemos obviar el codigo o indicarle que utilizaremos las credenciales por defecto
Código vb:
Ver original
  1. HttpWRequest.Credentials = CredentialCache.DefaultCredentials

Autenticación integrada
Debemos darle las credenciales apropiadas

Código vb:
Ver original
  1. Dim creds As New Net.NetworkCredential(USERNAME, PSSWD, Domain)
  2. HttpWRequest.Credentials = creds

Buffer de escritura
Otro tema a tener en cuenta es si la escritura se realiza directamente al flujo de salida o se retiene en buffer para luego ser enviado.
Para la mayoría de las aplicaciones es más cómodo utilizar el buffer ya que nos permite manejar de forma más simple los errores, la escritura directa se utiliza para envíos de stream, para enviar archivos de gran tamaño con control de progreso en el envío, etc.
Código vb:
Ver original
  1. HttpWRequest.AllowWriteStreamBuffering = True

Enviar datos
Ahora si, pasado el certificado y la autenticación ahora vamos a enviar los datos.
Primero tener en cuenta que si se van a enviar archivos se debe utilizar el contentType=”multipart/form-data” que es distinto de cuando se envía solamente cadenas (contentType=”application/x-www-form-urlencoded” )

Enviar solamente cadenas
Cuando se requiere enviar datos de cadena hay que generar una cadena igual a la del metodo “GET“, que en lugar de concatenarla a la URL se envía por “POST”.
Vi algunas implementaciones donde envían archivos como cadenas codificados en base64, si bien en principio esto funciona no lo recomiendo ya que para eso esta el otro enctype (multipart/form-data)
Código vb:
Ver original
  1. HttpWRequest.Method = "POST"
  2. HttpWRequest.ContentType = "application/x-www-form-urlencoded"
  3. 'Generar cadena igual que para el metodo get
  4. Dim data As StringBuilder = New StringBuilder()
  5. data.Append("param01=" + HttpUtility.UrlEncode("valor01"))
  6. data.Append("&param02=" + HttpUtility.UrlEncode("valor02"))
  7. data.Append("&param03=" + HttpUtility.UrlEncode("valor03"))
  8.  
  9. 'Crear array de bytes de la cadena  
  10. Dim byteData() As Byte
  11. byteData = UTF8Encoding.UTF8.GetBytes(data.ToString())
  12. 'Setear el largo del stream  
  13. HttpWRequest.ContentLength = byteData.Length
  14. 'Escribir datos
  15. Dim postStream As Stream = Nothing
  16. postStream = wr.GetRequestStream()
  17. postStream.Write(byteData, 0, byteData.Length)
  18.  
  19. 'Enviar los datos (si buffer está activado) y recuperar la respuesta
  20. Dim Response As HttpWebResponse
  21. Response = wr.GetResponse()

Enviar archivos

Para enviar archivo se debe utilizar el contentType “multipart/form-data” del método “POST” esta codificación es una estructura de datos que permite incluir en la misma el contenido de los archivo. Es la que utilizan los exploradores para enviar archivos cuando se crean los forms con input de tipo file.

Código HTML:
Ver original
  1. <form name="formDocs" method="post" action="pagina.asp" enctype="multipart/form-data">
  2.         <input type="hidden" name="param01" value="valor01"/>
  3.         <input type="file" name=" archivo" />
  4.         <input type="submit" />
  5. </form>

Este el el código
Código vb:
Ver original
  1. Dim LocalFile As String = "c:\archivo_a_enviar.txt"
  2. HttpWRequest.Method = "POST"
  3. 'Hay que generar un limite y asegurarnos que sea único
  4. 'Por ejemplo
  5. Dim limite As String = "----------" & DateTime.Now.Ticks.ToString("x")
  6. HttpWRequest.ContentType = "multipart/form-data; boundary=" & limite
  7.  
  8. Dim sb As StringBuilder = New StringBuilder()
  9. 'Por cada parametro hay que generar una estructura que varía
  10. 'si es de archivo o no
  11.  
  12. 'Parámnetro de cadena
  13. sb.Append("--")
  14. sb.Append(limite)
  15. sb.Append(vbNewLine)
  16. sb.Append("Content-Disposition: form-data; name=""")
  17. sb.Append("param01")
  18. sb.Append("""")
  19. sb.Append(vbNewLine)
  20. sb.Append(vbNewLine)
  21. sb.Append("param_valor01")
  22. sb.Append(vbNewLine)
  23.  
  24. 'Parámnetro de archivo
  25. sb.Append("--")
  26. sb.Append(limite)
  27. sb.Append(vbNewLine)
  28. sb.Append("Content-Disposition: form-data; name=""")
  29. sb.Append("sampfile")
  30. sb.Append("""; filename=""")
  31. sb.Append(Path.GetFileName(LocalFile))
  32. sb.Append("""")
  33. sb.Append(vbNewLine)
  34. sb.Append("Content-Type: ")
  35. sb.Append("application/octet-stream")
  36. sb.Append(vbNewLine)
  37. sb.Append(vbNewLine)
  38.  
  39. 'pasamos la cadena a matriz de bytes
  40. Dim postHeader As String = sb.ToString()
  41. Dim postHeaderBytes As Byte() = Encoding.UTF8.GetBytes(postHeader)
  42.  
  43. 'Crear la string de límite final como matriz de bytes
  44. Dim limiteBytes As Byte() = Encoding.UTF8.GetBytes(vbNewLine & "--" + limite + vbNewLine)
  45.  
  46.  
  47. 'Crear un stream con el archivo
  48. Dim fileStream As FileStream = New FileStream(LocalFile, FileMode.Open, FileAccess.Read)
  49.  
  50. 'Calcular el largo del contenido
  51. Dim length As Long = postHeaderBytes.Length + fileStream.Length + limiteBytes.Length
  52. HttpWRequest.ContentLength = length
  53.  
  54. Dim stream As Stream = wr.GetRequestStream()
  55. 'Escribir cabecera
  56. stream.Write(postHeaderBytes, 0, postHeaderBytes.Length)
  57. 'Escribir contenido del archivo
  58. Dim buffer As Byte() = {}
  59. ReDim buffer(fileStream.Length - 1)
  60.  
  61. Dim bytesRead As Integer = 0
  62. bytesRead = fileStream.Read(buffer, 0, buffer.Length)
  63. While bytesRead <> 0
  64.   stream.Write(buffer, 0, bytesRead)
  65.   bytesRead = fileStream.Read(buffer, 0, buffer.Length)
  66. End While
  67.  
  68. 'Escribir el límite final
  69. stream.Write(limiteBytes, 0, limiteBytes.Length)
  70.  
  71. 'Enviar los datos (si buffer está activado) y recuperar la respuesta
  72. Dim Response As HttpWebResponse
  73. Response = wr.GetResponse()

Última edición por jmo25; 02/02/2010 a las 13:56
  #6 (permalink)  
Antiguo 02/02/2010, 13:34
 
Fecha de Ingreso: febrero-2010
Mensajes: 3
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: POST en vb.net

Les adjunto el codigo de un modulo que me funciona OK.
Recibe una estructura de parametros indicando si son archivos o cadenas, los envia al servidor y retorna el objeto response.

Saludos, espero les sea de utilidad

Código vb:
Ver original
  1. Imports System.IO
  2. Imports System.Net
  3. Imports System.Net.Security
  4. Imports System
  5. Imports System.Web
  6. Imports System.Security.Cryptography.X509Certificates
  7. Imports System.Text
  8.  
  9. Module utiles
  10.     Public Enum typeParam
  11.         param_string = 0
  12.         param_file = 1
  13.     End Enum
  14.     Public Structure tParam
  15.         Dim name As String
  16.         Dim value As String
  17.         Dim type As typeParam
  18.     End Structure
  19.  
  20.  
  21.  
  22.     Public Function requestHTTP(ByVal strURL As String, ByVal params() As tParam, Optional ByVal USERNAME As String = "", _
  23.                                  Optional ByVal PSSWD As String = "", _
  24.                                  Optional ByVal Domain As String = "") As HttpWebResponse
  25.  
  26.         '****************************************************************
  27.        'Genarar datos del POST en el stream tmpStream
  28.        '****************************************************************
  29.  
  30.         'Generar limite
  31.        Dim limite As String = "----------" & DateTime.Now.Ticks.ToString("x")
  32.  
  33.         'Generar contenido del post
  34.        Dim sb As StringBuilder = New StringBuilder()
  35.         Dim paramHeader As String
  36.         Dim paramHeaderBytes As Byte()
  37.         Dim tmpStream As Stream = New MemoryStream()
  38.         Dim buffer As Byte() = {}
  39.         Dim bytesRead As Integer = 0
  40.         Dim i As Integer
  41.         'Recorre cada parametro generando el arreglo de bytes y esribiendolos en el buffer de salida
  42.        For i = 0 To UBound(params)
  43.             sb = New StringBuilder()
  44.             If params(i).type = typeParam.param_string Then
  45.                 'Si es una cadena
  46.                sb.Append("--")
  47.                 sb.Append(limite)
  48.                 sb.Append(vbNewLine)
  49.                 sb.Append("Content-Disposition: form-data; name=""")
  50.                 sb.Append(params(i).name) 'Nombre del parametro
  51.                sb.Append("""")
  52.                 sb.Append(vbNewLine)
  53.                 sb.Append(vbNewLine)
  54.                 sb.Append(params(i).value) 'Valor del parametro
  55.                sb.Append(vbNewLine)
  56.                 'Escribir la cabecera del parametro en el tmpStream
  57.                paramHeader = sb.ToString()
  58.                 paramHeaderBytes = Encoding.UTF8.GetBytes(paramHeader)
  59.                 tmpStream.Write(paramHeaderBytes, 0, paramHeaderBytes.Length)
  60.             Else
  61.                 'Si es un archivo
  62.                sb.Append("--")
  63.                 sb.Append(limite)
  64.                 sb.Append(vbNewLine)
  65.                 sb.Append("Content-Disposition: form-data; name=""")
  66.                 sb.Append(params(i).name) 'Nombre del parametro
  67.                sb.Append("""; filename=""")
  68.                 sb.Append(Path.GetFileName(params(i).value)) 'Nombre del archivo
  69.                sb.Append("""")
  70.                 sb.Append(vbNewLine)
  71.                 sb.Append("Content-Type: ")
  72.                 sb.Append("application/octet-stream")
  73.                 sb.Append(vbNewLine)
  74.                 sb.Append(vbNewLine)
  75.  
  76.                 'Escribir la cabecera del parametro en el tmpStream
  77.                paramHeader = sb.ToString()
  78.                 paramHeaderBytes = Encoding.UTF8.GetBytes(paramHeader)
  79.                 tmpStream.Write(paramHeaderBytes, 0, paramHeaderBytes.Length)
  80.  
  81.                 Dim fileStream As FileStream = New FileStream(params(i).value, FileMode.Open, FileAccess.Read)
  82.  
  83.                 'Escribir el contenido del archivo
  84.                ReDim buffer(fileStream.Length - 1)
  85.                 bytesRead = fileStream.Read(buffer, 0, buffer.Length)
  86.                 While bytesRead <> 0
  87.                     tmpStream.Write(buffer, 0, bytesRead)
  88.                     bytesRead = fileStream.Read(buffer, 0, buffer.Length)
  89.                 End While
  90.  
  91.             End If
  92.         Next
  93.  
  94.         'Crear el string de límite final como matriz de bytes
  95.        Dim limiteBytes As Byte() = Encoding.UTF8.GetBytes(vbNewLine & "--" + limite + vbNewLine)
  96.  
  97.         'Escriba el límite final
  98.        tmpStream.Write(limiteBytes, 0, limiteBytes.Length)
  99.  
  100.  
  101.         '********************************************************************
  102.        'Enviar el request
  103.        '********************************************************************
  104.  
  105.         'Cuando utiliza protocolo HTTPS necesita una función de validación de certificado
  106.        'Para este caso la función devuelve siempre true
  107.        'Si no es HTTPS no utiliza esta funcion
  108.        ServicePointManager.ServerCertificateValidationCallback = New RemoteCertificateValidationCallback(AddressOf ValidateCertificate)
  109.  
  110.         'Crear el objeto HttpWebRequest con la url de la pagina destino
  111.        Dim HttpWRequest As HttpWebRequest = HttpWebRequest.Create(strURL)
  112.         'Si se le pasaron credenciales las asigna, sino utilizar las credenciales actuales
  113.        If (USERNAME <> "") Then
  114.             Dim creds As New Net.NetworkCredential(USERNAME, PSSWD, Domain)
  115.             HttpWRequest.Credentials = creds
  116.         Else
  117.             HttpWRequest.Credentials = CredentialCache.DefaultCredentials
  118.         End If
  119.  
  120.         'Habilitar el buffer, no se envían los datos hasta la sentencia GetResponse()
  121.        HttpWRequest.AllowWriteStreamBuffering = True
  122.  
  123.         HttpWRequest.Method = "POST"
  124.  
  125.         'Asignar el contentType con el limite
  126.        HttpWRequest.ContentType = "multipart/form-data; boundary=" & limite
  127.  
  128.  
  129.         tmpStream.Seek(0, SeekOrigin.Begin)
  130.         'asignar el largo del stream
  131.        HttpWRequest.ContentLength = tmpStream.Length
  132.         Dim stream As Stream = HttpWRequest.GetRequestStream()
  133.  
  134.         ReDim buffer(tmpStream.Length - 1)
  135.         bytesRead = tmpStream.Read(buffer, 0, buffer.Length)
  136.         While bytesRead <> 0
  137.             stream.Write(buffer, 0, bytesRead)
  138.             bytesRead = tmpStream.Read(buffer, 0, buffer.Length)
  139.         End While
  140.  
  141.         Dim Response As HttpWebResponse = Nothing
  142.         Try
  143.             Response = HttpWRequest.GetResponse()
  144.         Catch ex As Exception
  145.             Debug.Print(ex.Message)
  146.         End Try
  147.         Return Response
  148.     End Function
  149.  
  150.    
  151.  
  152.  
  153.     Private Function ValidateCertificate(ByVal sender As Object, ByVal certificate As X509Certificate, ByVal chain As X509Chain, ByVal sslPolicyErrors As SslPolicyErrors) As Boolean
  154.         Dim validationResult As Boolean
  155.         validationResult = True
  156.         '
  157.        ' policy code here ...
  158.        '
  159.        Return validationResult
  160.     End Function
  161.  
  162.     Function readFileHTTP(ByVal strURL As String) As Byte()
  163.         Dim res() As Byte = {}
  164.         Try
  165.             Dim fr As System.Net.HttpWebRequest
  166.             Dim targetURI As New Uri(strURL)
  167.             fr = DirectCast(System.Net.HttpWebRequest.Create(targetURI), System.Net.HttpWebRequest)
  168.             If (fr.GetResponse().ContentLength > 0) Then
  169.                 Dim str As New System.IO.StreamReader(fr.GetResponse().GetResponseStream())
  170.                 res = System.Text.ASCIIEncoding.ASCII.GetBytes(str.ReadToEnd())
  171.                 str.Close()
  172.             End If
  173.         Catch ex As System.Net.WebException
  174.         End Try
  175.  
  176.         Return res
  177.     End Function
  178.  
  179.  
  180. End Module
  #7 (permalink)  
Antiguo 02/02/2010, 17:16
Avatar de gnzsoloyo
Moderador criollo
 
Fecha de Ingreso: noviembre-2007
Ubicación: Actualmente en Buenos Aires (el enemigo ancestral)
Mensajes: 23.324
Antigüedad: 16 años, 5 meses
Puntos: 2658
Respuesta: POST en vb.net


Pero... Esto sería mucho más útil para todos si en lugar de ponerlo en un post viejo lo pusieras en una FAQ...
Los post hay que buscarlos, y mucho, en cambio las FAQ están siempre a mano.
__________________
¿A quién le enseñan sus aciertos?, si yo aprendo de mis errores constantemente...
"El problema es la interfase silla-teclado." (Gillermo Luque)
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 21:17.