Pergunta

Usando .Net 3.0 e VS2005.

Os objetos em questão são consumidos de um serviço WCF, então, serializado de volta em XML para uma API legado. Então ao invés de serialização o TestObject, foi serialização .TestObject que estava faltando o atributo [XmlRoot]; no entanto, toda a [XML *] atributos para a criança elementos estavam no código proxy gerado para que eles trabalharam muito bem. Assim, todos os elementos filhos funcionou muito bem, mas o elemento anexando não porque o atributo [XmlRoot] não foi incluído no código proxy gerado. O objeto original, que incluiu o atributo [XmlRoot] serializa bem manualmente.

Posso ter o código de proxy incluir o atributo [XmlRoot] para a classe proxy gerado serializa corretamente assim? Se eu não posso fazer isso eu suspeito que eu vou ter que uso [XmlType] mas que causa estragos menores exigindo-me a mudar outros componentes então eu prefiro a primeira. Eu também quero evitar ter que editar manualmente a classe de proxy gerada automaticamente.

Aqui está um código de exemplo (Eu incluí o cliente eo serviço no mesmo aplicativo porque este é rápido e para fins de teste. Comente a serviço de referência de código e adicionar a referência de serviço durante a execução do aplicativo, em seguida, uncomment o serviço código e run).

namespace SerializationTest {  
  class Program {  
    static void Main( string[] args ) {  

        Type serviceType = typeof( TestService );  
        using (ServiceHost host = new ServiceHost(   
            serviceType,   
            new Uri[] {   
                new Uri( "http://localhost:8080/" )  
            }  

        ))
        {

            ServiceMetadataBehavior behaviour = new ServiceMetadataBehavior();  
            behaviour.HttpGetEnabled = true;  
            host.Description.Behaviors.Add( behaviour );  

            host.AddServiceEndpoint( serviceType, new BasicHttpBinding(), "TestService" );  
            host.AddServiceEndpoint( typeof( IMetadataExchange ), new BasicHttpBinding(), "MEX" );  


            host.Open();  

            TestServiceClient client = new TestServiceClient();  
            localhost.TestObject to = client.GetObject();  

            String XmlizedString = null;  
            using (MemoryStream memoryStream = new MemoryStream()) {
                XmlSerializer xs = new XmlSerializer( typeof( localhost.TestObject ) );  
                using (XmlWriter xmlWriter = XmlWriter.Create(memoryStream)) {
                    xs.Serialize( xmlWriter, to );  
                    memoryStream = (MemoryStream)xmlWriter.BaseStream;  
                    XmlizedString = Encoding.UTF8.GetString( memoryStream.ToArray() );  
                    Console.WriteLine( XmlizedString );  
                }    
            }    
        }

        Console.ReadKey();  
    }  
}  

[Serializable]  
[XmlRoot( "SomethingElse" )]  
public class TestObject {  

    private bool _worked;  

    public TestObject() { Worked = true; }  

    [XmlAttribute( AttributeName = "AttributeWorked" )]  
    public bool Worked {  
        get { return _worked; }  
        set { _worked = value; }  
    }  
}  

[ServiceContract]  
public class TestService {  

    [OperationContract]  
    [XmlSerializerFormat]  
    public TestObject GetObject() {  
        return new TestObject();  
    }  
  }  
}  

Aqui está o XML isso gera.

<?xml version="1.0" encoding="utf-8"?>
<TestObject xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" AttributeWorked="true" /> 
Foi útil?

Solução

Eu encontrei alguém que fornece um meio para resolver esta situação:

de Matevz Gacnik Weblog

Usando essa abordagem de XmlAttributeOverrides, escrevi o seguinte:

    private static XmlSerializer GetOverridedSerializer()
    {
        // set overrides for TestObject element
        XmlAttributes attrsTestObject = new XmlAttributes();
        XmlRootAttribute rootTestObject = new XmlRootAttribute("SomethingElse");
        attrsTestObject.XmlRoot = rootTestObject;

       // create overrider
       XmlAttributeOverrides xOver = new XmlAttributeOverrides();
       xOver.Add(typeof(localhost.TestObject), attrsTestObject);

       XmlSerializer xSer = new XmlSerializer(typeof(localhost.TestObject), xOver);
       return xSer;
    }

Apenas colocar esse método na classe Program do seu exemplo, e substituir a seguinte linha no Main():

        //XmlSerializer xs = new XmlSerializer(typeof(localhost.TestObject));
        XmlSerializer xs = GetOverridedSerializer();

E, em seguida, correr para ver os resultados.

Aqui está o que eu tenho:

<?xml version="1.0" encoding="utf-8"?><SomethingElse xmlns:xsi="http://www.w3.o
rg/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" Attribu
teWorked="true" />

Outras dicas

== IF ==

Esta é apenas para o atributo XmlRoot. O XmlSerializer tem um construtor onde você pode especificar o atributo XmlRoot.

Kudos para csgero para apontando-o. Seu comentário deve ser a solução.

XmlSerializer Constructor (Type, XmlRootAttribute)

Inicializa uma nova instância do classe XmlSerializer que pode serializar objetos do tipo especificado em XML documentos e desserializar um XML documento no objeto do especificado tipo. Ele também especifica a classe para usar como o elemento raiz XML.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top