我正在迁移旧的NETCF 2.0应用程序,该应用程序使用Web服务到NETCF 3.5。外部服务器的Web服务保持不变,不做任何更改。我还使用VS 2008命令提示符新生成了 Reference.cs - 并且很高兴看到与使用VS 2005相同的结果。
我的问题与根标记中的名称空间定义有关,该类由webservice定义。 java webservice使用xmlns属性对其进行序列化,并且NETCF 3.5的XmlSerializer.Deserialize()
指责此属性抛出 InvalidOperationException 。使用此XML和XmlSerializer.Deserialize()
与NETCF 2.0一起工作正常。对象被反序列化为内存。
让一些代码片段让事情变得清晰。
InvalidOperationException-There is an error in XML document (2, 2).
InnerException: InvalidOperationException-<InstallDirective xmlns='java:my.foreign.namespace'> was not expected.
at System.Xml.Serialization.XmlSerializer.resolveDeserializingType(XmlReader reader, XmlSerializationReader serialReader, Boolean soap12)
at System.Xml.Serialization.XmlSerializer.Deserialize(XmlReader xmlReader, String encodingStyle)
at System.Xml.Serialization.XmlSerializer.Deserialize(Stream stream)
at My.Neat.Software.Bug.Test()
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="java:my.foreign.namespace")]
public partial class InstallDirective {
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public System.Nullable<System.DateTime> Date;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public JustAnotherThing JustAnotherThing;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public System.Nullable<short> Oid;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Filename;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Version;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Dir;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(IsNullable=true)]
public string Instructions;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("Scripts", IsNullable=true)]
public Script[] Scripts;
}
<?xml version="1.0" encoding="utf-8"?>
<InstallDirective xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="java:my.foreign.namespace">
<Date>2014-02-11T13:31:49.238+01:00</Date>
<JustAnotherThing>
<FileName>MyFunnyFile.txt</CabFileName>
<Checksum>e759af8bd5787e3f8d62245a7d6aa73d</Checksum>
<FileExists xsi:nil="true" />
<Name>MyFunnyFile</Name>
<Version>1.2</Version>
<Path xsi:nil="true" />
<DependsOn xsi:nil="true" />
<RegistryPath xsi:nil="true" />
</JustAnotherThing>
<Oid>1</Oid>
<Filename>MyFunnyFile.txt</Filename>
<Version>1.2</Version>
<Dir>\My\Path\To\Files</Dir>
<Instructions xsi:nil="true" />
<Scripts xsi:nil="true" />
</InstallDirective>
FileInfo directiveFile = new FileInfo(@"\tmp\install\funnyInstallDirective.xml");
XmlSerializer xmlSerializer = new XmlSerializer(typeof(InstallDirective));
TextReader reader = new StreamReader(directiveFile.OpenRead());
InstallDirective installDirective = (InstallDirective)xmlSerializer.Deserialize(reader); // BAM!
感谢您的帮助!
答案 0 :(得分:1)
确实.Net Compact Framework 2.0和3.5的XmlSerializer实现有所不同。这种“新”行为的解决方案也很容易。因为XmlSerializer - 在我的例子中 - 将XML序列化为“片段”,我们需要声明XmlRootAttribute。这是因为缺少在Reference.cs中序列化的类型的XmlRootAttribute注释。 为了向后兼容由NETCF 2.0实现序列化的XML,我们需要通过InstallDirective(Reference.cs)的定义添加命名空间。不幸的是,我发现没有以编程方式获得此功能。
在:
XmlSerializer xmlSerializer = new XmlSerializer(typeof(InstallDirective));
FileStream file = File.Create(@"\tmp\install\funnyInstallDirective.xml");
TextWriter writer = new StreamWriter(file);
xmlSerializer.Serialize(writer, installDirective);
后:
XmlRootAttribute att = new XmlRootAttribute(typeof(InstallDirective).Name);
att.Namespace = "java:my.foreign.namespace";
XmlSerializer xmlSerializer = new XmlSerializer(typeof(InstallDirective), att);
FileStream file = File.Create(@"\tmp\install\funnyInstallDirective.xml");
TextWriter writer = new StreamWriter(file);
xmlSerializer.Serialize(writer, installDirective);
回复问题ta.speot.is的here的积分。
<强> [UPDATE] 强> 当然,您可以使用Web服务类型的带注释的XmlTypeAttribute来美化它。看起来会这样。
XmlTypeAttribute ta = (XmlTypeAttribute)Attribute.GetCustomAttribute(typeof(InstallDirective), typeof(XmlTypeAttribute));
XmlRootAttribute att = new XmlRootAttribute(typeof(InstallDirective).Name);
att.Namespace = ta.Namespace;
XmlSerializer xmlSerializer = new XmlSerializer(typeof(InstallDirective), att);