Deserialize answer service soap in c #

0

I am currently receiving this response from a svc soap service:

<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Body>
      <soap:Fault>
         <faultcode>soap:Client</faultcode>
         <faultstring>[0417] - El identificador de petición y de solicitud no coinciden.</faultstring>
         <faultactor>Seguridad Social</faultactor>
         <detail>
            <Atributos xmlns="http://intermediacion.redsara.es/scsp/esquemas/V3/soapfaultatributos">
               <IdPeticion>HACSGTIC-2016111056-0036</IdPeticion>
               <NumElementos>1</NumElementos>
               <TimeStamp>2016-11-10T11:56:51.687+01.00</TimeStamp>
               <Estado>
                  <CodigoEstado>0417</CodigoEstado>
                  <LiteralError>[0417] - El identificador de petición y de solicitud no coinciden.</LiteralError>
                  <TiempoEstimadoRespuesta />
               </Estado>
               <CodigoCertificado>Q2827002CINSS001</CodigoCertificado>
            </Atributos>
         </detail>
      </soap:Fault>
   </soap:Body>
</soap:Envelope>

What I need is deserializar the xml Attributes since I have an object "Attributes" with the properties corresponding to the xml, then I put the class Attributes of the service reference:

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.6.1064.2")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://intermediacion.redsara.es/scsp/esquemas/V3/peticion")]
public partial class Atributos : object, System.ComponentModel.INotifyPropertyChanged {

    private string idPeticionField;

    private int numElementosField;

    private string timeStampField;

    private Estado estadoField;

    private CodigoCertificado codigoCertificadoField;

    /// <comentarios/>
    public string IdPeticion {
        get {
            return this.idPeticionField;
        }
        set {
            this.idPeticionField = value;
            this.RaisePropertyChanged("IdPeticion");
        }
    }

    /// <comentarios/>
    public int NumElementos {
        get {
            return this.numElementosField;
        }
        set {
            this.numElementosField = value;
            this.RaisePropertyChanged("NumElementos");
        }
    }

    /// <comentarios/>
    public string TimeStamp {
        get {
            return this.timeStampField;
        }
        set {
            this.timeStampField = value;
            this.RaisePropertyChanged("TimeStamp");
        }
    }

    /// <comentarios/>
    public Estado Estado {
        get {
            return this.estadoField;
        }
        set {
            this.estadoField = value;
            this.RaisePropertyChanged("Estado");
        }
    }

    /// <comentarios/>
    public CodigoCertificado CodigoCertificado {
        get {
            return this.codigoCertificadoField;
        }
        set {
            this.codigoCertificadoField = value;
            this.RaisePropertyChanged("CodigoCertificado");
        }
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName) {
        System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
        if ((propertyChanged != null)) {
            propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
}


[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.6.1064.2")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://intermediacion.redsara.es/scsp/esquemas/V3/peticion")]
public partial class Estado : object, System.ComponentModel.INotifyPropertyChanged {

    private string codigoEstadoField;

    private string codigoEstadoSecundarioField;

    private string literalErrorField;

    private int tiempoEstimadoRespuestaField;

    private bool tiempoEstimadoRespuestaFieldSpecified;

    /// <comentarios/>
    public string CodigoEstado {
        get {
            return this.codigoEstadoField;
        }
        set {
            this.codigoEstadoField = value;
            this.RaisePropertyChanged("CodigoEstado");
        }
    }

    /// <comentarios/>
    public string CodigoEstadoSecundario {
        get {
            return this.codigoEstadoSecundarioField;
        }
        set {
            this.codigoEstadoSecundarioField = value;
            this.RaisePropertyChanged("CodigoEstadoSecundario");
        }
    }

    /// <comentarios/>
    public string LiteralError {
        get {
            return this.literalErrorField;
        }
        set {
            this.literalErrorField = value;
            this.RaisePropertyChanged("LiteralError");
        }
    }

    /// <comentarios/>
    public int TiempoEstimadoRespuesta {
        get {
            return this.tiempoEstimadoRespuestaField;
        }
        set {
            this.tiempoEstimadoRespuestaField = value;
            this.RaisePropertyChanged("TiempoEstimadoRespuesta");
        }
    }

    /// <comentarios/>
    [System.Xml.Serialization.XmlIgnoreAttribute()]
    public bool TiempoEstimadoRespuestaSpecified {
        get {
            return this.tiempoEstimadoRespuestaFieldSpecified;
        }
        set {
            this.tiempoEstimadoRespuestaFieldSpecified = value;
            this.RaisePropertyChanged("TiempoEstimadoRespuestaSpecified");
        }
    }

    public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;

    protected void RaisePropertyChanged(string propertyName) {
        System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
        if ((propertyChanged != null)) {
            propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
        }
    }
}

/// <comentarios/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.6.1064.2")]
[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://intermediacion.redsara.es/scsp/esquemas/V3/peticion")]
public enum CodigoCertificado {

    /// <comentarios/>
    Q2827002CINSS001,
}

***** This is my code that deserializes the xml to the object "Attributes":

    public static T Deserializar<T>(string respuesta, string nameSpace, string xpath = "//soap:Envelope/soap:Body/p:Respuesta")
    {


        T objetoDeserializado = default(T);
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(respuesta);

        Dictionary<string, string> nsAdicionales = new Dictionary<string, string>();
        nsAdicionales.Add("s", "http://www.w3.org/2003/05/soap-envelope");
        nsAdicionales.Add("soap", "http://schemas.xmlsoap.org/soap/envelope/");
        nsAdicionales.Add("i", "http://www.w3.org/2001/XMLSchema-instance");
        nsAdicionales.Add("p", nameSpace);
        XmlNamespaceManager nsm = new XmlNamespaceManager(xmlDoc.NameTable);
        foreach (string prefijo in nsAdicionales.Keys)
        {
            nsm.AddNamespace(prefijo, nsAdicionales[prefijo]);
        }
        XmlNode nodoObjeto = xmlDoc.SelectSingleNode(xpath, nsm);
        if (nodoObjeto != null)
        {

            try
            {
                //Se añade el atributo XmlRootAttribute para aquellos casos que esté definido el objeto
                //con un nombre y se utilice con otro.
                XmlRootAttribute xRoot = new XmlRootAttribute();
                xRoot.ElementName = nodoObjeto.Name;
                xRoot.Namespace = nodoObjeto.NamespaceURI;
                var serializer = new System.Xml.Serialization.XmlSerializer(typeof(T), xRoot);
                XmlReader xmlReader = nodoObjeto.CreateNavigator().ReadSubtree();
                var obj = serializer.Deserialize(xmlReader);
                objetoDeserializado = ((T)obj);
            }
            catch (Exception ex)
            {
                respuesta = "Error al intentar deserializar el objeto soap: " + ex.Message;
            }
        }

        return objetoDeserializado;
    }

Where T is of the type "SCSP.ServiciosCompartidos.INSS.ConsultaPrestaciones.Atributos" well, it does not give an error, but if we see the object Deserializado, it puts all the values as NULL

Help please.

    
asked by ararb78 11.11.2016 в 10:36
source

1 answer

0

The problem is that the namespaces do not correspond between the XML and the classes you use for deserialization.

In your classes, everyone defines the namespace as link :

[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="http://intermediacion.redsara.es/scsp/esquemas/V3/peticion")]

But the node Atributos in your XML defines a different namespace, link :

<Atributos xmlns="http://intermediacion.redsara.es/scsp/esquemas/V3/soapfaultatributos">

You will have to find out why this difference exists, but the point is that if you correct the namespace in your XML, you will see that now it will try to deserialize the values in the classes and their respective properties.

Additional note

Problem aside, I warn you that maybe you have a problem with:

<TiempoEstimadoRespuesta />

... since I do not think I can deserialize an empty node to a field of type int . I warn you if you receive an error after correcting the main problem.

    
answered by 11.11.2016 / 17:08
source