Spanish [SOLUCIONADO] Subir archivo a webservice asp.net

Xicu

Active Member
Licensed User
Longtime User
Necesito subir un archivo a un webservice asp.net. De hecho el webservice funciona correctamente. Este es el webservice:

B4X:
<WebMethod> _
    Public Function UploadFile(f As Byte(), fileName As String) As String
        ' the byte array argument contains the content of the file
        ' the string argument contains the name and extension
        ' of the file passed in the byte array
        Try
            ' instance a memory stream and pass the
            ' byte array to its constructor
            Dim ms As New MemoryStream(f)
            ' instance a filestream pointing to the
            ' storage folder, use the original file name
            ' to name the resulting file
            Dim fs As FileStream = New FileStream(System.Web.Hosting.HostingEnvironment.MapPath("~/Prueba/") + fileName, FileMode.Create)
            ' write the memory stream containing the original
            ' file as a byte array to the filestream
            ms.WriteTo(fs)
            ' clean up
            ms.Close()
            fs.Close()
            fs.Dispose()
            ' return OK if we made it this far
            Return "OK"

        Catch ex As Exception
            ' return the error message if the operation fails
            Return ex.Message.ToString()

        End Try

    End Function

El webservice acepta los siguientes protocolos:
HTTP POST, HTTP GET, SOAP 1.1, and SOAP 1.2.
En concreto en el test form del webservice el formato para http post seria:
B4X:
HTTP POST

The following is a sample HTTP POST request and response. The placeholders shown need to be replaced with actual values.

POST /prueba.asmx/UploadFile HTTP/1.1
Host: XXX.XXX.XXX.XXX
Content-Type: application/x-www-form-urlencoded
Content-Length: length

f=string&f=string&fileName=string

HTTP/1.1 200 OK
Content-Type: text/xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<string xmlns="http://www.prueba.com/">string</string>

¿Es posible subir un archivo mediante este webservice usando el objeto job.postfile?. Creo que usa http post (corrijanme si no es correcto).
He buscado por todo el foro, y unicamente encuentro ejemplos para un webservice php.
¿Alguien dispone de un pequeño ejemplo de codigo para usar el job.posfile para webservice asp.net?
Y si no es posible.¿Alguna alternativa?
 
Last edited:

Xicu

Active Member
Licensed User
Longtime User
Bueno, al final he encontrado una alternativa usando el protocolo SOAP con el cual he conseguido subir al servidor cualquier tipo de archivo:), usando job.PostString.
Con job.postfile no ha habido forma de obtener resultados positivos. :(
 
Last edited:

Heppy

Active Member
Licensed User
Longtime User
Gracias por postear que te ha funcionado.

Puedes argumentar un poquito más sobre el asunto.

No tengo pensado nada sobre el tema, la transferencia la hago siempre en local con SMB, pero quisiera recopilar un post o varios con soluciones, trucos, etc.

Muchas gracias
 

Xicu

Active Member
Licensed User
Longtime User
Disculpa HEPPY por mi pobre explicación en la respuesta anterior.
De entrada estaba molesto :mad: por la pobre respuesta recibida en el foro en ingles sobre el tema, y la nula respuesta en el foro español, por lo que no pretendia compartir la solucion encontrada (me costo bastante tiempo encontrar la solucion). Ha sido tu solicitud la que me ha hecho reflexionar, y en consecuencia me gustaria hacer un llamamiento a todos los que nos aprovechamos de la informacion aportada por otros foreros:
Debemos tomar conciencia de que para un buen funcionamiento del foro, no solo debemos recibir, tambien debemos aportar.
Como yo aprovecho de las aportaciones de otros, quiero compartir con vosotros la solución que me funcionó.

Bueno dicho todo esto, voy al grano:

En lugar de centrarme en el protocolo HTTP POST, me he centrado en el SOAP 1,2, basandome en la semi-respuesta que obtuve en http://www.basic4ppc.com/android/fo...le-to-c-asp-net-webservice.32262/#post-272979.
Lo primero debemos obtener el formato para el protocolo http SOAP 1,2 que requiere nuestro servicio y que obtenemos cuando hacemos el test form.
El webservice utilizado es el descrito anteriormente, y el formato que requiere es:
B4X:
POST /miservicio.asmx HTTP/1.1
Host: XXX.XXX.XXX.XXX
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <UploadFile xmlns="http://www.misservicios.com/">
      <f>base64Binary</f>
      <fileName>string</fileName>
    </UploadFile>
  </soap12:Body>
</soap12:Envelope>
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <UploadFileResponse xmlns="http://www.misservicios.com/">
      <UploadFileResult>string</UploadFileResult>
    </UploadFileResponse>
  </soap12:Body>
</soap12:Envelope>

Observamos que precisa de un parametro f de tipo base64Binary (es el archivo en si en forma de cadena Base64) y otro filename de tipo string (corresponde al nombre del archivo). Estos valores y nombres dependen del diseño en si del webservice

En nuestra aplicación Basic4android, añadimos la libreria httputils2 y creamos un procedimiento SubirArchivoConSOAP en el cual haremos lo siguiente:
- 1º convertimos el archivo que queremos subir en una cadena tipo Base64Binary
- 2º creamos un string llamado XML con la estructura XML igual al test del webservice substituyendo los marcadores de posicion por sus correspondientes valores
-3º Hacemos la llamada al servicio con job.poststring y definimos el job1.GetRequest.SetContentType

B4X:
Sub SubirArchivoConSOAP

     '1- convertimos el archivo que queremos subir en cadena Base64Str
    Private Base64Con As Base64Image
    Private B64Str As String = Base64Con.EncodeFromImage(RUTAARCHIVO, NOMBREARCHIVO)
    Private job1 As HttpJob
    '2-Construimos la cadena con la estructura XML igual al test del webservice substituyendo los marcadores de posicion por sus correspondientes valores
    Dim XML As String
    XML = ""
     XML = XML & "<?xml version='1.0' encoding='utf-8'?>"
    XML = XML & "<soap12:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap12='http://www.w3.org/2003/05/soap-envelope'>"
    XML = XML & "<soap12:Body>"
    XML = XML & "<UploadFile xmlns='http://www.miservicio.com/'>"
    XML = XML & "<f>" & B64Str & "</f>"
    XML = XML & "<fileName>" & NOMBREARCHIVO & "</fileName>"
    XML = XML & "</UploadFile>"
    XML = XML & "</soap12:Body>"
    XML = XML & "</soap12:Envelope>"
    XML = XML.Replace("'", Chr(34))
    job1.Initialize("JOBSOAP", Me)
    '3º llamamos al servicio, definiendo el tipo de contenido
    job1.PostString ("http://XXX.XXX.XXX.XXX/MiServicio.asmx", XML)
    job1.GetRequest.SetContentType("application/soap+xml")
End Sub

Despues podriamos crear el procedimiento jobdone, en el cual podriamos recuperar la respuesta del webservice leyendo el parametro UploadFileResult, que si todo ha ido correctamente deberia ser "OK"
 
Last edited:

Heppy

Active Member
Licensed User
Longtime User
Muchas gracias por tu tiempo.

Tu preocupación ante la participación de los usuarios es algo que estamos intentando mejorar.

No eres el único que lo piensa, como bien sabes.

Gran trabajo y me gustaría colgarlo en el indice de temas Solucionado, si te parece bien.
 

Xicu

Active Member
Licensed User
Longtime User
Me parece bien.
Y si alguien descubre alguna alternativa para subir archivos a un servicio asp.net, o mejora en el código, por favor que la comparta
 
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Nadal:

Gracias por tu aporte.

Debemos tomar conciencia de que para un buen funcionamiento del foro, no solo debemos recibir, tambien debemos aportar.
Como yo aprovecho de las aportaciones de otros, quiero compartir con vosotros la solución que me funcionó.
Seria interesante esto que has dicho lo añadieras al post :

Mejorar el foro “Spanish Forum”
http://www.basic4ppc.com/android/forum/threads/mejorar-el-foro-“spanish-forum”.39799/

De esta forma, haber si entre todos hacemos tomar conciencia al resto del foro. Es decepcionante como tu dices que solo busquemos recibir sin aportar nunca nada.

Y ya de paso, si no te es mucha molestia, podrias cambiar la cabecera y añadir [SOLUCIONADO] ?, es para que la gente del foro que pueda tener tu mismo problema sepa que se resolvió, por otra parte Heppy creó un post con preguntas solucionadas y seria interesante que la añadieras si no te es mucha molestia.

El post de Heppy:
Indice de temas con [Solucionado]
http://www.basic4ppc.com/android/forum/threads/indice-de-temas-con-solucionado.44948/

Gracias


Saludos
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Nadal:

Gracias por tu apoyo en los dos Post, en el de Heppy y en el mio. Quizas no me expresé bien, lo que pretendia no era que nos apoyaras, si no que expresaras lo que expresaste en este mismo post:
Debemos tomar conciencia de que para un buen funcionamiento del foro, no solo debemos recibir, tambien debemos aportar.
Como yo aprovecho de las aportaciones de otros, quiero compartir con vosotros la solución que me funcionó.

Que añadieras ese comentario como otra idea para mejorar el foro.

Y en el de Heppy darle permiso para colgarlo.

Saludos
 

bravox

Member
Licensed User
Longtime User
Hello Xicu,
Regarding to your webservice code in message #1, how did you call this webservice from b4a code by using Httpjob.PostFile?
Could you please share a sample code.
 

StefanoAccorsi

Member
Licensed User
Longtime User
Disculpa HEPPY por mi pobre explicación en la respuesta anterior.
De entrada estaba molesto :mad: por la pobre respuesta recibida en el foro en ingles sobre el tema, y la nula respuesta en el foro español, por lo que no pretendia compartir la solucion encontrada (me costo bastante tiempo encontrar la solucion). Ha sido tu solicitud la que me ha hecho reflexionar, y en consecuencia me gustaria hacer un llamamiento a todos los que nos aprovechamos de la informacion aportada por otros foreros:
Debemos tomar conciencia de que para un buen funcionamiento del foro, no solo debemos recibir, tambien debemos aportar.
Como yo aprovecho de las aportaciones de otros, quiero compartir con vosotros la solución que me funcionó.

Bueno dicho todo esto, voy al grano:

En lugar de centrarme en el protocolo HTTP POST, me he centrado en el SOAP 1,2, basandome en la semi-respuesta que obtuve en http://www.basic4ppc.com/android/fo...le-to-c-asp-net-webservice.32262/#post-272979.
Lo primero debemos obtener el formato para el protocolo http SOAP 1,2 que requiere nuestro servicio y que obtenemos cuando hacemos el test form.
El webservice utilizado es el descrito anteriormente, y el formato que requiere es:
B4X:
POST /miservicio.asmx HTTP/1.1
Host: XXX.XXX.XXX.XXX
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <UploadFile xmlns="http://www.misservicios.com/">
      <f>base64Binary</f>
      <fileName>string</fileName>
    </UploadFile>
  </soap12:Body>
</soap12:Envelope>
HTTP/1.1 200 OK
Content-Type: application/soap+xml; charset=utf-8
Content-Length: length

<?xml version="1.0" encoding="utf-8"?>
<soap12:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://www.w3.org/2003/05/soap-envelope">
  <soap12:Body>
    <UploadFileResponse xmlns="http://www.misservicios.com/">
      <UploadFileResult>string</UploadFileResult>
    </UploadFileResponse>
  </soap12:Body>
</soap12:Envelope>

Observamos que precisa de un parametro f de tipo base64Binary (es el archivo en si en forma de cadena Base64) y otro filename de tipo string (corresponde al nombre del archivo). Estos valores y nombres dependen del diseño en si del webservice

En nuestra aplicación Basic4android, añadimos la libreria httputils2 y creamos un procedimiento SubirArchivoConSOAP en el cual haremos lo siguiente:
- 1º convertimos el archivo que queremos subir en una cadena tipo Base64Binary
- 2º creamos un string llamado XML con la estructura XML igual al test del webservice substituyendo los marcadores de posicion por sus correspondientes valores
-3º Hacemos la llamada al servicio con job.poststring y definimos el job1.GetRequest.SetContentType

B4X:
Sub SubirArchivoConSOAP

     '1- convertimos el archivo que queremos subir en cadena Base64Str
    Private Base64Con As Base64Image
    Private B64Str As String = Base64Con.EncodeFromImage(RUTAARCHIVO, NOMBREARCHIVO)
    Private job1 As HttpJob
    '2-Construimos la cadena con la estructura XML igual al test del webservice substituyendo los marcadores de posicion por sus correspondientes valores
    Dim XML As String
    XML = ""
     XML = XML & "<?xml version='1.0' encoding='utf-8'?>"
    XML = XML & "<soap12:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap12='http://www.w3.org/2003/05/soap-envelope'>"
    XML = XML & "<soap12:Body>"
    XML = XML & "<UploadFile xmlns='http://www.miservicio.com/'>"
    XML = XML & "<f>" & B64Str & "</f>"
    XML = XML & "<fileName>" & NOMBREARCHIVO & "</fileName>"
    XML = XML & "</UploadFile>"
    XML = XML & "</soap12:Body>"
    XML = XML & "</soap12:Envelope>"
    XML = XML.Replace("'", Chr(34))
    job1.Initialize("JOBSOAP", Me)
    '3º llamamos al servicio, definiendo el tipo de contenido
    job1.PostString ("http://XXX.XXX.XXX.XXX/MiServicio.asmx", XML)
    job1.GetRequest.SetContentType("application/soap+xml")
End Sub

Despues podriamos crear el procedimiento jobdone, en el cual podriamos recuperar la respuesta del webservice leyendo el parametro UploadFileResult, que si todo ha ido correctamente deberia ser "OK"

Hi @Xicu, thank you for yuor example. I was working on the same exact .NET example but I can't make your b4a code work. First of all I'm using OkHttpUtils, but even in HttpUtils2

B4X:
job1.GetRequest.SetContentType("application/soap+xml")

seems to be inexistent: no SetContentType method for GetRequest. Then I get "Internal server error" if I try to run the code.

My question is: I read that you call "MiServicio.asmx" but how do you let your webserver know you want to use the "UploadFile" method?

Or there's another way to call a SOAP WS within b4a? Thank you.
 

StefanoAccorsi

Member
Licensed User
Longtime User
Hi @Xicu, thank you for yuor example. I was working on the same exact .NET example but I can't make your b4a code work. First of all I'm using OkHttpUtils, but even in HttpUtils2

B4X:
job1.GetRequest.SetContentType("application/soap+xml")

seems to be inexistent: no SetContentType method for GetRequest. Then I get "Internal server error" if I try to run the code.

My question is: I read that you call "MiServicio.asmx" but how do you let your webserver know you want to use the "UploadFile" method?

Or there's another way to call a SOAP WS within b4a? Thank you.

Ok it was 3 days I was trying to make it work. The error was I forgot to add reference to OkHttp lib that manages "Result" object.
This is mandatory to add the line:

B4X:
job1.GetRequest.SetContentType("application/soap+xml")

Now it works. Thank you.
 
Top