Atributo não incluídos na classe proxy gerado
-
03-07-2019 - |
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" />
Solução
Eu encontrei alguém que fornece um meio para resolver esta situação:
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.