使用.Net 3.0和VS2005。
有问题的对象从WCF服务中获取,然后序列化为旧版API的XML。因此,不是序列化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" />
答案 0 :(得分:1)
== IF ==
这仅适用于XmlRoot
属性。 XmlSerializer
有一个构造函数,您可以在其中指定XmlRoot
属性。
感谢csgero指点它。他的评论应该是解决方案。
XmlSerializer Constructor (Type, XmlRootAttribute)
初始化一个新的实例 可以序列化的
XmlSerializer
类 指定类型的对象到XML中 文档,并反序列化XML 将文档转换为指定的对象 类型。它还指定了类 用作XML根元素。
答案 1 :(得分:-1)
我发现有人提供了解决这种情况的方法:
使用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" />