Атрибут не включен в сгенерированный прокси-класс - PullRequest
2 голосов
/ 01 октября 2008

Использование .Net 3.0 и VS2005.

Рассматриваемые объекты потребляются из службы WCF, а затем сериализуются обратно в XML для устаревшего API. Таким образом, вместо сериализации TestObject, это была сериализация .TestObject, в которой отсутствовал атрибут [XmlRoot]; однако все атрибуты [Xml *] для дочерних элементов были в сгенерированном прокси-коде, поэтому они работали просто отлично. Таким образом, все дочерние элементы работали просто отлично, но включающий элемент не работал, потому что атрибут [XmlRoot] не был включен в сгенерированный прокси-код. Исходный объект, который включал атрибут [XmlRoot], сериализуется в порядке вручную.

Могу ли я, чтобы код прокси включал атрибут [XmlRoot], чтобы сгенерированный класс прокси также корректно сериализовался? это вызывает незначительный хаос, требующий от меня изменения других компонентов, поэтому я бы предпочел первый. Я также хочу избежать необходимости вручную редактировать автоматически сгенерированный прокси-класс.

Вот пример кода (я включил клиента и службу в одно приложение, потому что это быстро и для целей тестирования. Закомментируйте код ссылки на службу и добавьте ссылку на службу во время работы приложения, затем раскомментируйте службу код и запустить.)

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();  
    }  
  }  
}  

Вот XML-файл, который он генерирует.

<?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" /> 

Ответы [ 2 ]

1 голос
/ 23 июня 2009

== IF ==

Это только для атрибута XmlRoot. У XmlSerializer есть один конструктор, в котором вы можете указать атрибут XmlRoot.

Благодарность csgero за указание на это. Его комментарий должен быть решением.

XmlSerializer Constructor (Type, XmlRootAttribute)

Инициализирует новый экземпляр XmlSerializer класс, который может сериализоваться объекты указанного типа в XML документы и десериализацию XML документ в объект указанного тип. Он также определяет класс для использовать в качестве корневого элемента XML.

0 голосов
/ 07 октября 2008

Я нашел кого-то, кто предоставляет средства для решения этой ситуации:

Блог Матевза Гакника

Используя этот подход XmlAttributeOverrides, я написал следующее:

    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;
    }

Просто поместите этот метод в класс Program вашего примера и замените следующую строку в Main():

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

А затем бегите, чтобы увидеть результаты.

Вот что я получил:

<?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" />
...