使用.Net 3.0和VS2005。

有问题的对象从WCF服务中使用,然后序列化回XML以用于旧版API。因此,不是序列化TestObject,而是序列化.TestObject,它缺少[XmlRoot]属性。但是,子元素的所有[Xml *]属性都在生成的代理代码中,因此它们工作正常。因此,所有子元素都可以正常工作,但封闭元素却没有,因为[XmlRoot]属性未包含在生成的代理代码中。包含[XmlRoot]属性的原始对象可以手动进行很好的序列化。

我是否可以让代理代码包含[XmlRoot]属性,以便生成的代理类也可以正确序列化?如果我无法做到这一点,我怀疑我将不得不使用[XmlType],但是这会造成严重的破坏,需要我更改其他组件,因此我希望使用前者。我还希望避免手动编辑自动生成的代理类。

这是一些示例代码(我将客户端和服务包含在同一个应用程序中,因为这是快速且出于测试目的。注释掉服务引用代码并在运行应用程序时添加服务引用,然后取消注释服务代码并运行)

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

最佳答案

我发现有人提供了解决这种情况的方法:

Matevz Gacnik's Weblog

使用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" />

关于c# - 该属性未包含在生成的代理类中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/159373/

10-12 01:55