none
Subir un archivo a traves de json y recibir respuesta RRS feed

  • Pregunta

  • Estimados, necesito subir un archivo a un webservice que espera un formato json como el siguiente:

    {
    rutSender integer
    dvSender string
    rutCompany integer
    dvCompany string
    archivo string($binary)
    }

    donde en archivo se debe adjuntar un xml.

    He tratado de hacer el código, aunque mi fuerte no es C# debo hacerlo en este lenguaje. Tengo desarrollado el siguiente código, pero al ejecutarlo me sale error ("Conexión anulada").

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.IO;
    using System.Security.Cryptography;
    using System.Security.Cryptography.X509Certificates;
    using System.Diagnostics;
    using System.Security.Permissions;
    using System.Net;
    using System.Xml.Linq;
    using Newtonsoft.Json;
    
    namespace EnvioBoletas
    {
        class Program
        {
            public class Product
            {
                public int rutSender { get; set; }
                public string dvSender { get; set; }
                public int rutCompany { get; set; }
                public string dvCompany { get; set; }
                public byte[] archivo { get; set; }
            }
    
            public Byte[] fileToByteArray(String fileName)
            {
                BinaryReader binReader = new BinaryReader(File.Open(fileName, FileMode.Open, FileAccess.Read));
                binReader.BaseStream.Position = 0;
                byte[] binFile = binReader.ReadBytes(Convert.ToInt32(binReader.BaseStream.Length));
                binReader.Close();
                return binFile;
            }
    
            public void Envio_Load(ref String rutEmi, String rutEmp, String url, string token)
            {
                //// Prepare  los paramentros para utilizarlos
                //// en el envio del documento.
                string rutEmisor = string.Empty;
                string rutEmpresa = string.Empty;
                rutEmisor = rutEmi.Replace("-", string.Empty);
                rutEmpresa = rutEmp.Replace("-", string.Empty);
                ////
                //// Recupere el cuerpo y digito verificador de los 
                //// rut involucrados.
                string pRutEmisor = rutEmisor.Substring(0, (rutEmisor.Length - 1));
                string pDigEmisor = rutEmisor.Substring(rutEmisor.Length - 1);
                string pRutEmpresa = rutEmpresa.Substring(0, (rutEmpresa.Length - 1));
                string pDigEmpresa = rutEmpresa.Substring(rutEmpresa.Length - 1);
                // System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls;
                ServicePointManager.SecurityProtocol = (SecurityProtocolType)3072; //TLS 1.2
                ServicePointManager.SecurityProtocol = (SecurityProtocolType)768; //TLS 1.1
    
                
    
            var product = new Product
                {
                    rutSender = Convert.ToInt32(pRutEmisor),
                    dvSender = pDigEmisor,
                    rutCompany = Convert.ToInt32(pRutEmpresa),
                    dvCompany = pDigEmpresa,
                    archivo = fileToByteArray(url)
                };
    
                string json = JsonConvert.SerializeObject(product);
                   
    
                
    
                //// Defina que ambiente utilizar.
                //// Certificacion 
                string pUrl = "https://pangal.sii.cl/recursos/v1/boleta.electronica.envio";
    
                ////
                //// Cree los parametros del header.
                //// Token debe ser el valor asignado por el SII
                string pMethod = "POST";
                string pAccept = "application/json"; 
               
                string pToken = "TOKEN={0}";
    
                ////
                //// Cree un nuevo request para iniciar el proceso
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(pUrl);
                request.Method = pMethod;
                request.Accept = pAccept;
               
    
                ////
                //// Agregar el content-type
                request.ContentType = "multipart/form-data";  
                
               // byte[] byteArray = Encoding.UTF8.GetBytes(json);
                request.ContentLength =json.Length;
               
    
                ////
                
                request.Headers.Add("Cookie", string.Format(pToken, token));
                
    
                ////
                //// Defina el user agent
                request.UserAgent = "Mozilla/4.0 ( compatible; PROG 1.0; Windows NT)";
                request.KeepAlive = false;
                request.Timeout = 10000;
                request.ProtocolVersion = HttpVersion.Version10;
    
               
    
                ////
                //// Recupere el streamwriter para escribir la secuencia
                try
                {
    
                    using (StreamWriter sw = new StreamWriter(request.GetRequestStream(), Encoding.GetEncoding("UTF-8")))
                    {
                        sw.Write(json);//.ToString());
                    }
    
                }
                catch (Exception ex)
                {
                    ////
                    //// Error en el metodo
                    //// Error del formato del envio
    
    
                }
    
                #endregion
    
                
                #region ENVIA Y SOLICITA RESPUESTA
    
                try
                {
    
                    ////
                    //// Defina donde depositar el resultado
                    string respuestaSii = string.Empty;
    
                    ////
                    //// Recupere la respuesta del sii
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                        {
                            respuestaSii = sr.ReadToEnd().Trim();                        
                            url = url.Substring(0, url.Length - 12);
                            url = url + @"\RespuestaSii.txt";
                            System.IO.File.WriteAllText(@url, respuestaSii);
    
                        }
    
                    }
    
                    ////
                    //// Hay respuesta?
                    if (string.IsNullOrEmpty(respuestaSii))
                        throw new ArgumentNullException("Respuesta del SII es null");
    
    
                    ////
                    //// Interprete la respuesta del SII.
                    //// respuestaSii contiene la respuesta del SII acerca del envio en formato XML
    
    
                }
                catch (Exception ex)
                {
    
                    ////
                    //// Error en el metodo
                    //// No fue posible enviar o recepcionar la respuesta del SII
    
    
                }
    
                #endregion
    
            }
    
            static void Main(string[] args)
            {
                if (args.Length == 0)
                { System.Console.WriteLine("No se han ingresado argumentos"); }
                Program pro = new Program();
                pro.Envio_Load(ref args[0], args[1], args[2], args[3]);
            }
        }
    }
    

    el xml lo convierto a bytearray para adjuntarlo a json, pero no se si lo estoy haciendo bien o no.

    Por favor, si alguien me da una ayuda, ya no se que más hacer. Gracias

    martes, 29 de diciembre de 2020 17:22

Respuestas

  • Vale, creo el problema está aquí
    request.ContentLength =json.Length;

    Comenta o elimina esta línea ya que estás estableciendo un dato que puede ser incorrecto al no pasarle la longitud en bytes.

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    jueves, 31 de diciembre de 2020 17:09
    Moderador

Todas las respuestas

  • Aunque no hay suficiente información para dar una respuesta definitiva, lo de "conexión anulada" me suena a que está fallando el protocolo.

    Y el protocolo podría fallar debido a que estás cambiando dos veces el tipo de TLS. Primero pones 1.2 y luego lo cambias a 1.1. Esto NO habilita los dos a la vez, sino que deja únicamente el último. Si tu servidor requiere TLS 1.2 y le estás dejando solo el 1.1, puede que por eso falle.

    En estos casos, y si no se soluciona haciendo pruebas, a veces no hay más remedio que recurrir a activar un capturador de paquetes tal como WireShark y examinar la negociación del protocolo, a ver qué es lo que está fallando y por qué "anula" la conexión. Esto lo tiene que hacer alguien que comprenda cómo funcionan internamente estos protocolos. Yo no sabría hacerlo, pero sí he visto a algún "gurú" depurar estas cosas, echarle un vistazo a la captura de paquetes, y deducir en un minuto cuál era el problema. Si no consigues solucionarlo jugando con el ServicePointManager, puede que te merezca la pena buscarte a un experto y que te dedique unos minutos a examinar una captura de tráfico.

    martes, 29 de diciembre de 2020 17:51
    Moderador
  • Hola,

    Gracias por levantar tu consulta en los foros de MSDN.

    Eric Ruiz

    ____________________________

    Por favor recuerde "Marcar como respuesta" las respuestas que hayan resuelto su problema, es una forma común de reconocer a aquellos que han ayudado, y hace que sea más fácil para los otros visitantes encontrar la solución más tarde.

    Si tiene algún cumplido o reclamo sobre el soporte de MSDN siéntase en la libertad de contactar MSDNFSF@microsoft.com.

    martes, 29 de diciembre de 2020 19:01
    Moderador
  • Estimado, probé con ambos protocolos e incluso sin ninguno y me sigue apareciendo el mensaje de "Solicitud anulada: cancelada la solicitud".

    Yo creo que puede deberse a como está creado el json

    miércoles, 30 de diciembre de 2020 14:04
  • Revisando el código creo que el json no se lo estoy agregando al request. Cómo se lo debería agregar?
    miércoles, 30 de diciembre de 2020 14:32
  • Revisando el código creo que el json no se lo estoy agregando al request.

    Sí, se lo estás agregando donde haces esto:

    sw.Write(json)

    El sw está conectado al Request.GetRequestStream, por lo que el Write le inyecta el json.

    Esto se hace cuando el json es "enorme" (muchos megabytes). Para un json relativamente pequeño, a mí me parece que esto es "matar moscas a cañonazos". Pero en cualquier caso, no veo motivo para que esto cause ningún error. Tiene que haber algún otro problema, pero no lo veo a simple vista con solo examinar el código fuente.

    miércoles, 30 de diciembre de 2020 15:34
    Moderador
  • Cual sería entonces la forma más adecuada para enviar un archivo json??
    jueves, 31 de diciembre de 2020 13:15
  • Hola, pero el servicio espera un objeto con propiedad archivo de tipo string (lo que indica de binary es que lo envíes como base64)

    var product = new Product
                {
                    rutSender = Convert.ToInt32(pRutEmisor),
                    dvSender = pDigEmisor,
                    rutCompany = Convert.ToInt32(pRutEmpresa),
                    dvCompany = pDigEmpresa,
                    archivo = Convert.ToBase64String(fileToByteArray(url))
                };


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    jueves, 31 de diciembre de 2020 13:28
    Moderador
  • También has verificado si esto es correcto?

    request.ContentType = "multipart/form-data";  

    Porque si el servicio espera un json ese valor debe ser igual a 

    application/json

    Tienes documentación de ese servicio al que llamas?


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos



    jueves, 31 de diciembre de 2020 13:32
    Moderador
  • Lo he probado de distintas maneras y aún me arroja el mensaje de anulada la conexión:

    jueves, 31 de diciembre de 2020 16:36
  • Hola. Prueba a configurar así tú Visual Studio para que en depuración de detenga tu flujo del programa al encontrar una excepción como se indica en Administración de excepciones con el depurador en Visual Studio

    Indicar al depurador que se interrumpa en las excepciones no controladas por el usuario

    El depurador puede interrumpir la ejecución en el momento en el que se produce una excepción para que, así, pueda examinarla antes de que se invoque un controlador.

    En la ventana Configuración de excepciones (Depurar > Windows > Configuración de excepciones), expanda el nodo para obtener una categoría de excepciones, como Excepciones de Common Language Runtime.

    Marca el Common Language Runtime y verás que se detiene la ejecución en alguna línea. Por favor indícanosla.


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    jueves, 31 de diciembre de 2020 16:57
    Moderador
  • Vale, creo el problema está aquí
    request.ContentLength =json.Length;

    Comenta o elimina esta línea ya que estás estableciendo un dato que puede ser incorrecto al no pasarle la longitud en bytes.

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    jueves, 31 de diciembre de 2020 17:09
    Moderador
  • Estimado, antes que todo, espero tengan un buen inicio de año y muchas gracias por su ayuda.

    Hice lo que me indicaste en cuanto a comentariar el request.ContentLength, ahora no me arroja el mensaje de conexion anulada sino otro que dice "La longitud no puede ser inferior a cero.\r\nNombre del parámetro: Length"

    al parecer por ahí está el problema.

    lunes, 4 de enero de 2021 14:23
  • Hola, en qué línea concreta de produce la excepción? Puedes depurar paso a paso y ver dónde falla e indicarlo? Gracias

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    lunes, 4 de enero de 2021 14:42
    Moderador
  • No te da problemas cuando haces el request? un error 400.

    Yo llevo un rato intentando con restclient y me funcionan los demas metodos pero no el Envio , dice no estar autenticado y me pregunto si es por que la semilla y el token lo vas a obtener al a de los servidores Apicert o api  y los envios los haces en pangal o rahue


    lunes, 4 de enero de 2021 14:55
  • Puede ser esta? 

    url = url.Substring(0, url.Length - 12);

    Has verificado en un punto de ruptura si url tiene datos?



    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    lunes, 4 de enero de 2021 14:58
    Moderador
  • Justamente te iba a decir que el problema estaba en esa línea, por el largo del url, pero ya lo solucioné.

    Ahora ya sube el archivo pero me manda error 501.

    Viendo cuakl es el problema según el SII se debe a esto

    "Este tipo de error se da por problemas de comunicación entre el navegador utilizado y el servidor del SII, cuando ocurre, se recomienda volver a intentar más tarde."

    Lo hé intentado varias veces pero sigue igual.

    lunes, 4 de enero de 2021 15:47
  • Pablo, efectivamente la semilla y el token se obtienen desde Apicert o Api pero el token se debe usar en pangal o rahue. Compara tu código con el mio si te sirve algo
    lunes, 4 de enero de 2021 15:49
  • Donde estas apuntando en la peticion ? pangal o rahue

    A que url le estas pidiendo el token ?

    Yo obtengo el error 400 con el código que presentas arriba haciendo la petición a pangal 

    lunes, 4 de enero de 2021 15:53
  • Efectivamente estoy haciendo las pruebas hacia pangal y me sale el error 501, por lo que veo en la página del API el error 500 es un error interno, no habla del error 501 pero debe ser lo mismo.

    El token lo pido a apicert.sii.cl
    • Editado vicvil lunes, 4 de enero de 2021 16:05
    lunes, 4 de enero de 2021 16:03

  • Yo sigo con el problema del error 400 en la petición , podrías postear la version de como lo tienes ahora por si algo ha variado? , en paralelo estoy contactando con gente del SII por mail , por que la mesa de ayuda aun no esta instruida sobre estos temas.

    lunes, 4 de enero de 2021 16:13
  • Hablar con la ayuda del sii es perder el tiempo porque nunca saben nada.

    El código es el mismo sólo comentarié la línea del request.contentlength

    lunes, 4 de enero de 2021 16:21
  • Se supone que es un servicio abierto para quien se quiera certificar , tu ya certificaste a la empresa con la que estas haciendo las pruebas o recién estas en eso ? 

    Tuviste que habilitar algún permiso adicional?

    lunes, 4 de enero de 2021 16:36
  • No nada, ningún permiso especial.
    lunes, 4 de enero de 2021 16:41
  • Es muy extraño que teniendo el mismo código tenga un resultado diferente. 

    Lo unico que varia es el certificado con el que estamos autenticando y los valores de las variables , pero eso no deberia ser el origen del problema.

    Lo otro que podría variar es el framework  (4.6.1 en mi caso ) o las dlls por ejemplo Newtonsoft (12.0.0.0) que tengas referenciadas que pueden tener alguna diferencia

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())

    esa es la linea que me arroja la excepcion y dice error 400 , pero no da mayores detalles.

    
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    lunes, 4 de enero de 2021 17:11
  • El error 400 dice que es "Petición con error"
    lunes, 4 de enero de 2021 17:48
  • Hola, un error 400 es un BadRequest, esto es, estás enviando un cuerpo o body en tu petición que el sistema no lo admite. Tal vez porque no envías algún campo obligatorio o algo por el estilo. Si os parece cierto el hilo ya que la consulta está resuelta. El problema es del extremo del SII. 

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    lunes, 4 de enero de 2021 18:00
    Moderador
  • Error 501. https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/501

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    lunes, 4 de enero de 2021 18:01
    Moderador
  • Lo tengo presente estimado  , el problema es que no da mayores detalles , de todas formas agradezco las respuestas  y espero que pronto llegues a buen puerto , yo por mi parte seguire intentando con apis rest u otros metodos , dado que no he logrado un resultado satisfactorio de momento.

    lunes, 4 de enero de 2021 18:06
  • Ok muchas gracias Sergio por tus respuestas. Al parecer ahora es un problema de la API así que tendré que verlo directamente con ellos.
    lunes, 4 de enero de 2021 18:23
  • de casualidad recibes esto ? 

    <HTML>
    <HEAD>
    <TITLE>Error 501</TITLE>
    </HEAD>
    <BODY>
    <div align="center"><center>
    <table border="0" cellpadding="0" cellspacing="0" width="630">
    <tr>
    <td colspan="2"></tr>
    <tr>
    <td></td>
    <td></td>
    </tr>
    <tr>
    <td colspan="2"><b><font face="Arial" size="2"><br>
    </font><font face="Arial" size="4">ERROR : 501 </font></b></td>
    </tr>
    <tr>
    <td height="40" colspan="2"><hr>
    </td>
    </tr>
    <tr>
    <td colspan="2"><p align="justify"><font face="Arial" size="2"><h4>
    Error : ptr NULL (ptrTkn)
    </h4>
    <h4>
    Codigo de Error : 01.02.160.413.211.1000.
    </h4>
    </font></p></td>
    </tr>
    </table>
    </center></div>
    </BODY>
    </HTML>

    lunes, 4 de enero de 2021 18:26
  • Exactamente

    lunes, 4 de enero de 2021 18:40
  • Si te fijas en los curl representa asi la forma de cargar el archivo  

    "archivo=@EnvioD_DTE_965480_39_14(1).xml;type=text/xml"

    No se si por detrás hará la codificación ,pero ya sea subiendo o no el archivo , no logro un resultado diferente.


    lunes, 4 de enero de 2021 18:42
  • Según lo que aparece ahí, espera un archivo de texto o xml, pero al parecer no se puede subir así.
    lunes, 4 de enero de 2021 19:15
  • Pablo te sigue el mismo problema (501)?
    lunes, 4 de enero de 2021 20:16
  • Si , he probado codificando el archivo de manera diferente o simplemente no adjuntandolo pero el error es el mismo.

    lunes, 4 de enero de 2021 20:57
  • Yo Aún continúo con el error 501, no sé que más hacer.
    martes, 5 de enero de 2021 18:34
  • Yo tampoco he tenido feedback respecto al error , pero me llama mucho la atencion que aunque corrompas el TOKEN o pongas lo que sea , no te da el error de no autorizado que te da si en lugar de declarar una cookie lo agregas como un encabezado http.

    De hecho la documentacion dice : 

    • Como este recurso requiere autorización se debe ontener un TOKEN y agregar al Header llamado Cookie con la el valor del TOKEN={token}, ejemplo: P7VQKYLDNHJGP\n > Cookie:TOKEN=P7VQKYLDNHJGP \n

    Pero si lo mandas como un Header , arroja el mensaje que no trae token.

    Y como independiente del valor del token que mande indica el mismo error , creo que nisiquiera se esta autenticando o bien se cae antes de hacer esa validación.

    martes, 5 de enero de 2021 22:04
  • Hola, podéis mostrar la URL de documentación? Viendo lo que os pasa creo que el problema es que espera una cookie de autenticación. Para ello deberéis de establecer en la petición un nuevo CookieContainer en vuestro HttpWebRequest.

    Podéis implementar este método de extensión

    public static bool TryAddCookie(this HttpWebRequest httRequest, Cookie cookie)
    {
        if (httpRequest == null)
        {
            return false;
        }
    
        if (httpRequest.CookieContainer == null)
        {
            httpRequest.CookieContainer = new CookieContainer();
        }
    
        httpRequest.CookieContainer.Add(cookie);
        return true;
    }

    Y luego usarlo así

    HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create( uri );
    webRequest.TryAddCookie(new Cookie("TOKEN","<valor Token>"));







    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos


    martes, 5 de enero de 2021 22:12
    Moderador
  • Sergio  , no puedo adjuntar urls pero la palabra clave que te serviria es bolcoreinternetui 

    Esto es el curl que te da en el ejemplo 

    curl -X POST "https://pangal.sii.cl/recursos/v1/boleta.electronica.envio" -H  "accept: application/json" -H  "User-Agent: Mozilla/4.0 ( compatible; PROG 1.0; Windows NT)" -H  "Cookie: YZVQNQY4J5DT9" -H  "Content-Type: multipart/form-data" -F "rutSender=1" -F "dvSender=9" -F "rutCompany=2" -F "dvCompany=7"

    martes, 5 de enero de 2021 22:33
  • Ahhh. No me había dado cuenta que es un multipart formdata. Se envía de diferente forma. 

    Echa un ojo a la respuesta de aqui. Verás que se le pasa un NameValueCollection y se inserta en la petición cada campo del formulario.


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 6 de enero de 2021 0:01
    Moderador
  • Sergio : 

    Hice un cliente usando la filosofia planteada y el resultado es el mismo , por ende ya tengo 3 formas de hacerlo y todas devuelven el mismo error 501.

    Creo que claramente algo no esta bien pero en el SII (proveedor de la Api) de momento no he conseguido feedback

    miércoles, 6 de enero de 2021 3:34
  • Correcto. Debe ser problema del servicio. Supongo que habrá donde hacer un ticket de soporte. Saludos

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 6 de enero de 2021 8:51
    Moderador
  • Lamentablemente no hay una forma directa de pedir soporte para un asunto en especifico , todo recae a la misma plataforma.

    Ahora probé con la herramienta postman importando el yaml y adivina el resultado ? error 501

    miércoles, 6 de enero de 2021 21:46
  • Envié correo al sii, me pidieron todos los datos, el xml, el código, el token, etc.

    y me respondieron que me fijara bien a que servidor lo estaba enviando porque nadie presentaba el problema...cueck

    Ni siquiera vieron el código porque ahí aparece el url a donde se envía y es el mismo que me dijeron.

    Para probar cambié al servidor a apicert y ahí no me manda el error 501 sino que "Acceso denegado" eso corresponde al token.

    Sigo insistiendo con el SII a ver si alguien se digna en darme una respuesta como corresponde, cualquier novedad avisaré.


    viernes, 8 de enero de 2021 20:48
  • vamos a sacarlo entre todos...

    actualmente paso la seguridad pero no me reconoce la variable rutCompany, de acuerdo al CURL a usar este deberia ser el consumo en .net

    var handler = new HttpClientHandler();
    handler.UseCookies = false; 
    
    using (var httpClient = new HttpClient(handler))
    {
        using (var request = new HttpRequestMessage(new HttpMethod("POST"), "https://pangal.sii.cl/recursos/v1/boleta.electronica.envio"))
        {
            request.Headers.TryAddWithoutValidation("accept", "application/json");
            request.Headers.TryAddWithoutValidation("User-Agent", "Mozilla/4.0 ( compatible; PROG 1.0; Windows NT)");
            request.Headers.TryAddWithoutValidation("Cookie", "TOKEN=DH3AX8O3L9KLO"); 
    
            var multipartContent = new MultipartFormDataContent();
            multipartContent.Add(new StringContent("6312824"), "rutSender");
            multipartContent.Add(new StringContent("4"), "dvSender");
            multipartContent.Add(new StringContent("76631410"), "rutCompany");
            multipartContent.Add(new StringContent("4"), "dvCompany");
            var file1 = new ByteArrayContent(File.ReadAllBytes("Boleta_1.xml"));
            file1.Headers.Add("Content-Type", "text/xml");
            multipartContent.Add(file1, "archivo", Path.GetFileName("Boleta_1.xml"));
            request.Content = multipartContent; 
    
            var response = await httpClient.SendAsync(request);
        }
    }


    • Editado AlexPavez lunes, 11 de enero de 2021 3:37
    lunes, 11 de enero de 2021 3:37
  • Hola, el content type que estás estableciendo debería ser 
    multipart/form-data

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    lunes, 11 de enero de 2021 7:40
    Moderador
  • el objeto multipartformdatacontent... al asignarlo al content del request establece el tag de multipart/form-data ?

    de hecho lo puedes leer con Content.ReadAsStringAsync().Result;

    var multipartContent = new MultipartFormDataContent();
            multipartContent.Add(new StringContent("6312824"), "rutSender");
            multipartContent.Add(new StringContent("4"), "dvSender");
            multipartContent.Add(new StringContent("76631410"), "rutCompany");
            multipartContent.Add(new StringContent("4"), "dvCompany");
            var file1 = new ByteArrayContent(File.ReadAllBytes("Boleta_1.xml"));
            file1.Headers.Add("Content-Type", "text/xml");
            multipartContent.Add(file1, "archivo", Path.GetFileName("Boleta_1.xml"));
            request.Content = multipartContent; 


    lunes, 11 de enero de 2021 13:19
  • Hola,

    Tengo un problema similar,  ya que obtengo el error 400.

    He realizado varias modificaciones y no he logrado dar con la solución. 

    Yo tengo el código en VB.net y es un tanto diferente al que se ha planteando VicVil al inicio de este hilo,

    pero persigue el mismo objetivo. Enviar la boleta electrónica, junto con los campos obligatorios según

    lo establecido en la documentación de la API del SII, para BE.

    Cualquier ayuda se agradece.



    lunes, 8 de febrero de 2021 23:15
  • Hola, estoy intentando enviar la boleta electrónica a SII y como paso con Uds. entrega un http 501, intente además realizar el envio por SOAP UI (herramienta para poder probar WS) y me entrega el mismo error, ahora llame al SII y me dijeron que enviara un correo al dte_certificacion@sii.cl pero aun no tengo respuesta, ahora investigando cuando es multipart/form-data se debe agregar un boundary pero aun falta algo en el envio para que sea recibido por SII.

    myReq = (HttpWebRequest)HttpWebRequest.Create("https://pangal.sii.cl/recursos/v1/boleta.electronica.envio");
    myReq.Method = "POST";
        string formDataBoundary = String.Format("----------{0:N}", Guid.NewGuid());
    
         myReq.ContentType = "multipart/form-data; boundary=" + formDataBoundary;
         myReq.Accept = "application/json";
         myReq.UserAgent = "Mozilla/4.0 ( compatible; PROG 1.0; Windows NT)";
         myReq.KeepAlive = false;
         myReq.Headers.Add("Cookie", token);

    y boundary se ocuparía a si:

                secuencia.Append(formDataBoundary + "\r\n"); //<--Boundary.
                secuencia.Append("Content-Dis-data; name=\"rutSender\"\r\n");
                secuencia.Append("Content-Type: Text/ plain; charset=US-ASCII\r\n");
                secuencia.Append("Content-Transfer - Encoding:  8Bit\r\n");
                //secuencia.Append("\r\n");
                secuencia.Append(pRutEmisor + "\r\n");
                secuencia.Append(formDataBoundary + "\r\n");
                secuencia.Append("Content-Dis-data; name=\"dvSender\"\r\n");
                secuencia.Append("Content-Type: Text/ plain; charset=US-ASCII\r\n");
                secuencia.Append("Content-Transfer - Encoding:  8Bit\r\n");
                //secuencia.Append("\r\n");
                secuencia.Append(pDigEmisor + "\r\n");
                secuencia.Append(formDataBoundary + "\r\n");
                secuencia.Append("Content-Dis-data; name=\"rutCompany\"\r\n");
                secuencia.Append("Content-Type: Text/ plain; charset=US-ASCII\r\n");
                secuencia.Append("Content-Transfer - Encoding:  8Bit\r\n");
                //secuencia.Append("\r\n");
                secuencia.Append(pRutEmpresa + "\r\n");
                secuencia.Append(formDataBoundary + "\r\n");
                secuencia.Append("Content-Dis-data; name=\"dvCompany\"\r\n");
                secuencia.Append("Content-Type: Text/ plain; charset=US-ASCII\r\n");
                secuencia.Append("Content-Transfer - Encoding:  8Bit\r\n");
                //secuencia.Append("\r\n");
                secuencia.Append(pDigEmpresa + "\r\n");
                secuencia.Append(formDataBoundary + "\r\n");
    
                string xmlFile = "C:/Trabajo/Otros/Facturacion Electronica/tmp/DTE_39_ENV20210209120011.xml";
    
                secuencia.Append("Content-Dis-data; name=\"archivo\"; filename=@DTE_39_ENV20210209120011.xml\r\n");
                secuencia.Append("Content-Type: text/xml\r\n");
                secuencia.Append("Content-Transfer - Encoding: binary\r\n");
                //secuencia.Append("Content-Transfer - Encoding: binary");
                secuencia.Append("\r\n");
    
                //// Lea el documento xml que se va a enviar al SII
                xmlBoletaDoc = XDocument.Load(xmlFile, LoadOptions.PreserveWhitespace);
    
                //// Cargue el documento en el objeto secuencia
                secuencia.Append("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
                secuencia.Append(xmlBoletaDoc.ToString(SaveOptions.DisableFormatting));
                secuencia.Append("\r\n");
                secuencia.Append(formDataBoundary);

    bueno si tiene mas información o si esta resuelto, ojala lo pudieran compartir, gracias.


    miércoles, 10 de febrero de 2021 18:50
  • Hola, el swagger con la definición del servicio es este?

    https://www4c.sii.cl/bolcoreinternetui/api/


    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 10 de febrero de 2021 20:07
    Moderador
  • Hola, si ese es el link donde la esta la documentación de la API.
    miércoles, 10 de febrero de 2021 20:12
  • Hola, puedes poner aquí algunos valores de prueba de forma data? Y algún fichero que enviar? Con datos "falsos" ya sabes .. 

    Si se solucionó tu consulta no olvides marcar la respuesta. Si te ayudó, vótala como útil. Saludos

    miércoles, 10 de febrero de 2021 20:22
    Moderador
  • Ese código es más aplicable a los Servicios de envío de Facturas , que usan  un boundary para recepcion de DTES , AECS Y Libros entre otros.(Yo lo uso para Facturar , Ceder y receder documentos , hacer rendiciones diarias por ejemplo)

    El error 501 es que te esta reconociendo mal el token , si bien lo recibe y pasa la validación de campo por que si está , no es valido.

    Te sugiero usar RestClient con c# o el lenguaje que te acomode y usar Postman apuntando a la Url de la api y con esto te detallara todos los métodos.

    Como ya tienes avanzado la obtención de Semilla y token  , solo tendrías que completar los parámetros en Postman y hacer tus pruebas , luego esto te auto genera un cliente con el botón code .

    Yo llevo 2 meses esperando respuesta de parte del SII y me dicen que tienen un margen de 6 para responder.

    Así que debemos arreglárnoslas solitos o esperar...saludos!

    sábado, 13 de febrero de 2021 17:44
  • Amigo esto te puede servir para ver el error en precisión 

                try
                {
                    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                    {
                        using (StreamReader streamReader = new StreamReader(response.GetResponseStream()))
                        {
                            respuestaSii = streamReader.ReadToEnd().Trim();
                        }
                    }
                }
                catch (WebException ex)
                {
    
                    using (StreamReader streamReader = new StreamReader(ex.Response.GetResponseStream()))
                    {
                        respuestaSii = streamReader.ReadToEnd().Trim();
                    }
                }

    jueves, 25 de febrero de 2021 23:47
  • Estimados,

    Disculpen por retomar el tema, pero aún no he podido resolverlo del todo.

    Ahora estoy enviando el archivo y ya no me manda error 501, pero el servidor me manda respuesta "Acceso denegado", yo supongo que se debe al token aunque lo estoy enviando dentro del cuerpo.

    ¿Alguna idea por qué se debe dicho mensaje?

    martes, 9 de marzo de 2021 14:21
  • Me respondo a mi mismo,

    el problema era el servidor "apicert", lo cambié a "pangal" y pasó.

    Pero ahora me reclama que la variable "archivo" no va en el json, siendo que se lo estoy agregando en el request.

    request.AddParameter("archivo", file1);

    siendo file1 un ByteArrayContent

    jueves, 11 de marzo de 2021 15:04
  •  Sobre lo de los servers , recuerda que para el metodo de envío los servidores son diferentes a los de consulta , en este caso pangal y rahue respectivamente .

    Sobre tu archivo , no se si usas un rest client o un web request , en mi caso uso  :

      // Carga Xml con preserve white space , lee su contenido a traves del outer y pasa a byte[]

      

      Encoding encoding = Encoding.UTF8;
      byte[] docAsBytes = encoding.GetBytes(TuXml.OuterXml);

       request.AddFile("archivo", docAsBytes, "Nombre de tu XML", "application/xml");

    domingo, 28 de marzo de 2021 15:46