none
Métodos asincronos RRS feed

  • Pregunta

  • Hola 

    Como consumir métodos asincronos de un web service y como saber cuando ya respondio a la petición? lo estoy implementando de esta manera pero no se si es la manera adecuada

    private void btnFirmar_Click(object sender, EventArgs e)
            {
                try
                {
                    // Create a new XML document.
                    XmlDocument xmlDoc = new XmlDocument();
                    var uidCert = GetCertificateByPath();
    
                    using (var clientWs = new EnviarFactura.ec.gob.sri.celcer.RecepcionComprobantesOfflineService())
                    {
                        clientWs.Url = $"{sri_url}{"RecepcionComprobantesOffline"}";
                        clientWs.ClientCertificates.Add(uidCert);
    
                        FirmaXades firmaXades = new FirmaXades(SignMethod.RSAwithSHA1, DigestMethod.SHA1);
    
                        // Cargue un archivo XML en el objeto XmlDocument.
                        string path = System.Configuration.ConfigurationManager.AppSettings["testfiles.path"].ToString();
                        xmlDoc.Load(Path.Combine(path, "Factura_001-500-000000019_292.02_XXXXXXXXXXXXXXXXX.xml"));
                        xmlDoc.PreserveWhitespace = true;
    
    
                        firmaXades.SetContentEnveloped(xmlDoc);
                        firmaXades.Sign(uidCert, SignMethod.RSAwithSHA1);
    
                        clientWs.validarComprobanteAsync(System.Text.Encoding.UTF8.GetBytes(firmaXades.Document.InnerXml));
                        clientWs.validarComprobanteCompleted += ClientWsOnValidarComprobanteCompleted;
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"{ex.Message}", @"Prueba");
    
                }
            }
    
            string _mensaje = string.Empty;
            string _estadoAurorizacion = string.Empty;
    
            private void ClientWsOnValidarComprobanteCompleted(object sender, validarComprobanteCompletedEventArgs validarComprobanteCompletedEventArgs)
            {
                
             
                if (validarComprobanteCompletedEventArgs != null)
                {
                    //MessageBox.Show(
                    //    $"{validarComprobanteCompletedEventArgs.Result.estado}");
                    _estado = validarComprobanteCompletedEventArgs.Result.estado;
    
                    if (_estado == "RECIBIDA")
                    {
                        using (var client2Ws = new EnviarFactura.ec.gob.sri.celcer1.AutorizacionComprobantesOfflineService())
                        {
                            client2Ws.Url = $"{sri_url}{"AutorizacionComprobantesOffline"}";
                            var response2 =
                                client2Ws.autorizacionComprobante("XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX");
                            foreach (var encontrado in response2.autorizaciones.ToList())
                            {
                                MessageBox.Show(
                                    $"{encontrado.estado}{encontrado.comprobante}{encontrado.fechaAutorizacion}{encontrado.numeroAutorizacion}");
    
                            }
                        }
                    }
                }
            }

    No se como obtener la respuesta de ese metodo

    Si estuviera trabajando con este segundo metodo asincrono no logro llegar al mensaje la respuesta que espero

    public void autorizacionComprobanteAsync(string claveAccesoComprobante) {
                this.autorizacionComprobanteAsync(claveAccesoComprobante, null);
            }
            
            /// <remarks/>
            public void autorizacionComprobanteAsync(string claveAccesoComprobante, object userState) {
                if ((this.autorizacionComprobanteOperationCompleted == null)) {
                    this.autorizacionComprobanteOperationCompleted = new System.Threading.SendOrPostCallback(this.OnautorizacionComprobanteOperationCompleted);
                }
                this.InvokeAsync("autorizacionComprobante", new object[] {
                            claveAccesoComprobante}, this.autorizacionComprobanteOperationCompleted, userState);
            }
            
            private void OnautorizacionComprobanteOperationCompleted(object arg) {
                if ((this.autorizacionComprobanteCompleted != null)) {
                    System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                    this.autorizacionComprobanteCompleted(this, new autorizacionComprobanteCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
                }
            }

    Una vez que la respuesta es RECIBIDA debo utilizar el segundo WS de Autorización y recibir uno de los siguientes mensajes PPR(En procesamiento), AUT(Autorizado), NAT(No Autorizado)

    Gracias anticipadamente por su respuesta.

    Saludos!


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú


    martes, 8 de enero de 2019 21:29

Respuestas

  • hola

    que tipo de referencia realizaste al sevicio web? es un Service Reference o Web Reference

    porque si es Web Reference a un servicio asmx recuerdo que en el proxy crean los metodo que comienzan con el nombre BeginXX() y EndXX(), con estos realizas la llamada asincrona, indicando un metodo de callback

    Si tienes un evento validarComprobanteCompletedse supone que debes definir lo antes de invocar al metod async

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina


    • Editado Leandro TuttiniMVP martes, 8 de enero de 2019 22:59
    • Marcado como respuesta Pedro Ávila martes, 8 de enero de 2019 23:00
    • Desmarcado como respuesta Pedro Ávila martes, 8 de enero de 2019 23:00
    • Marcado como respuesta Pedro Ávila miércoles, 16 de enero de 2019 23:03
    martes, 8 de enero de 2019 22:59

Todas las respuestas

  • hola

    que tipo de referencia realizaste al sevicio web? es un Service Reference o Web Reference

    porque si es Web Reference a un servicio asmx recuerdo que en el proxy crean los metodo que comienzan con el nombre BeginXX() y EndXX(), con estos realizas la llamada asincrona, indicando un metodo de callback

    Si tienes un evento validarComprobanteCompletedse supone que debes definir lo antes de invocar al metod async

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina


    • Editado Leandro TuttiniMVP martes, 8 de enero de 2019 22:59
    • Marcado como respuesta Pedro Ávila martes, 8 de enero de 2019 23:00
    • Desmarcado como respuesta Pedro Ávila martes, 8 de enero de 2019 23:00
    • Marcado como respuesta Pedro Ávila miércoles, 16 de enero de 2019 23:03
    martes, 8 de enero de 2019 22:59
  • Hola Leandro

    Los dos servicios los he implementado por Web Reference.

    validarComprobanteCompleted

    Es lo que se me ocurrio para supuestamente esperar la respuesta del Web service

    La idea es cuando responda el primer WS y valide la respuesta que espero utilizar el segundo WS que también tengo que trabajarlo de manera asincrona, el problema que tengo en el segundo WS es que no puedo llegar o obtener la respuesta(el mensaje Autorizado.... no puedo obtener ninguno de los tres mensajes que devuelve)

    Saludos!


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú




    martes, 8 de enero de 2019 23:01
  • Leandro

    Estoy estoy viendo este manual 

    Communicating with XML Web Services Asynchronously

    En esta parte.

     PrimeFactorizer pf = new PrimeFactorizer();
    
              // Begin the Async call to Factorize.
                IAsyncResult ar = pf.BeginFactorize(factorizableNum, null, null);

    El método que estoy llamando es el asincrono pero es un void no me devuelve nada

    public void validarComprobanteAsync(byte[] xml) {
                this.validarComprobanteAsync(xml, null);
            }
            
            /// <remarks/>
            public void validarComprobanteAsync(byte[] xml, object userState) {
                if ((this.validarComprobanteOperationCompleted == null)) {
                    this.validarComprobanteOperationCompleted = new System.Threading.SendOrPostCallback(this.OnvalidarComprobanteOperationCompleted);
                }
                this.InvokeAsync("validarComprobante", new object[] {
                            xml}, this.validarComprobanteOperationCompleted, userState);
            }
            
            private void OnvalidarComprobanteOperationCompleted(object arg) {
                if ((this.validarComprobanteCompleted != null)) {
                    System.Web.Services.Protocols.InvokeCompletedEventArgs invokeArgs = ((System.Web.Services.Protocols.InvokeCompletedEventArgs)(arg));
                    this.validarComprobanteCompleted(this, new validarComprobanteCompletedEventArgs(invokeArgs.Results, invokeArgs.Error, invokeArgs.Cancelled, invokeArgs.UserState));
                }
            }

    Saludos!


    Pedro Ávila
    "El hombre sabio querrá estar siempre con quien sea mejor que él."
    Lima - Perú

    martes, 8 de enero de 2019 23:27
  • Hola. Cambia el orden de estas dos líneas

    clientWs.validarComprobanteAsync(System.Text.Encoding.UTF8.GetBytes(firmaXades.Document.InnerXml));
     clientWs.validarComprobanteCompleted += ClientWsOnValidarComprobanteCompleted;
                   

    Deberías primero suscribirte al evento y luego ejecutar el código asíncrono


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

    martes, 8 de enero de 2019 23:48
    Moderador
  • hola

    >>El método que estoy llamando es el asincrono pero es un void no me devuelve nada

    es un callback este recibe la repsuesta del servicio no tiene que retornar nada

    pero cuando usas BeginFactorize() no estas indicando ese callback que debe usar, creo que no analizaste bien el ejemplo de ese codigo, porque alli usa

    IAsyncResult ar = pf.BeginFactorize(factorizableNum, cb, pf);

    ese parametro "cb" es el mas importante, ya que indica que debe llamar cuandl vuelva la respuesta

    saludos


    Leandro Tuttini

    Blog
    MVP Profile
    Buenos Aires
    Argentina

    miércoles, 9 de enero de 2019 0:11