属性不包含在生成的代理类中

本文关键字:代理 包含 属性 | 更新日期: 2023-09-27 17:47:23

使用 .Net 3.0 和 VS2005。

有问题的对象从 WCF 服务中使用,然后序列化回旧版 API 的 XML。因此,它不是序列化测试对象,而是序列化。缺少 [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" /> 

属性不包含在生成的代理类中

==

IF ==

这仅适用于XmlRoot属性。XmlSerializer有一个构造函数,您可以在其中指定 XmlRoot 属性。

感谢csgero指出它。他的评论应该是解决方案。

XmlSerializer Constructor (Type, XmlRootAttribute)

初始化 XmlSerializer可以序列化的类 指定类型的对象到 XML 中 文档,并反序列化 XML 文档到指定的对象中 类型。它还指定要 用作 XML 根元素。

我找到了提供解决这种情况的方法的人:

马特夫兹·加茨尼克的博客

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