Pregunta

Quiero poder cargar una clase xml serializada en un Soap Envelope. Estoy empezando, así que no estoy llenando las entrañas, por lo que parece que:

<Envelope    
xmlns="http://schemas.xmlsoap.org/soap/envelope/" /> 

Quiero que aparezca como:

<Envelope    
xmlns="http://schemas.xmlsoap.org/soap/envelope/" ></Envelope>`


La clase que escribí es esta:

[System.SerializableAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "http://schemas.xmlsoap.org/soap/envelope/")]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "http://schemas.xmlsoap.org/soap/envelope/",ElementName="Envelope", IsNullable = true)]
public class TestXmlEnvelope
{
  [System.Xml.Serialization.XmlElement(ElementName="Body", Namespace="http://schemas.xmlsoap.org/soap/envelope/")]
  public System.Collections.ArrayList Body = new System.Collections.ArrayList();
} //class TestXmlEnvelope`

Estoy usando esto como ejemplo, ya que otras personas pueden quererlo en un elemento individual. Estoy seguro de que esto debe ser simple, pero lamentablemente no sé la palabra clave correcta para esto.

Como siempre, gracias por su ayuda.

[Editar] El error aparece cuando intento usar esta instrucción

System.Xml.Serialization.XmlSerializer xmlout = new System.Xml.Serialization.XmlSerializer(typeof(TestXmlEnvelope));
System.IO.MemoryStream memOut = new System.IO.MemoryStream();
xmlout.Serialize(memOut, envelope, namespc);
Microsoft.Web.Services.SoapEnvelope soapEnv = new Microsoft.Web.Services.SoapEnvelope();
soapEnv.Load(memOut);

Me da error " Elemento raíz no encontrado " ;.

[Editar] Solucioné el error, el problema era que después de serializar el objeto no configuré memOut.Position = 0. Aún así, espero que esta pregunta ayude a otras personas que quieran hacer esto.

¿Fue útil?

Solución

El problema principal aquí es que XmlSerializer llama a WriteEndElement() en XmlWriter cuando escribiría una etiqueta final. Sin embargo, esto genera la forma abreviada <tag/> cuando no hay contenido. WriteFullEndElement() escribe la etiqueta final por separado.

Puede inyectar su propio XmlTextWriter en el medio que el serializador usaría para exhibir esa funcionalidad.

Dado que serializer es el <=> apropiado, intente esto:

public class XmlTextWriterFull : XmlTextWriter
{
    public XmlTextWriterFull(TextWriter sink) : base(sink) { }

    public override void WriteEndElement()
    {
        base.WriteFullEndElement();
    }
}

...

var writer = new XmlTextWriterFull(innerwriter);
serializer.Serialize(writer, obj);

[Editar] para el caso de su código agregado, agregue constructores de fachada para:

public XmlTextWriterFull(Stream stream, Encoding enc) : base(stream, enc) { }
public XmlTextWriterFull(String str, Encoding enc) : base(str, enc) { }

Luego, use la secuencia de memoria como su secuencia interna en el constructor como antes:

System.IO.MemoryStream memOut = new System.IO.MemoryStream();
XmlTextWriterFull writer = new XmlTextWriterFull(memOut, Encoding.UTF8Encoding); //Or the encoding of your choice
xmlout.Serialize(writer, envelope, namespc);

Otros consejos

Nota para el registro: El OP estaba usando el *** Microsoft . *** Clase Web.Services.SoapEnvelope , que forma parte del producto WSE 1.0 extremadamente obsoleto. Esta clase deriva de la clase XmlDocument, por lo que es posible que se hayan visto los mismos problemas con XmlDocument.

Bajo ninguna circunstancia se debe usar WSE para ningún desarrollo nuevo, y si ya está en uso, el código debe migrarse lo antes posible. WCF o ASP.NET Web API son las únicas tecnologías que deberían usarse para los servicios web .NET en el futuro.

Las dos representaciones son equivalentes. ¿Por qué necesita que aparezca en la última forma?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top