DataContractSerializer.ReadObject() 与 SvcUtils.exe 一起使用时无法创建对象
DataContractSerializer.ReadObject() fails to create object when used with SvcUtils.exe
我运行SvcUtil.exe针对XSD文件生成class。然后尝试使用以下行从 XML 创建对象。我收到如下所示的错误。详细代码见下方
PersonType prs = (PersonType)xs.ReadObject(new MemoryStream(File.ReadAllBytes(sFileName)));
Error in line 3 position 58. Expecting element 'PersonType' from namespace 'http://service.a1.com/base1/2005/'.. Encountered 'Element' with name 'Person', namespace 'http://service.a1.com/base1/2005/'.
使用的命令
svcutil.exe" "C:\Temp\S1\UseXSDExe\UseXSDExe\Sample2\Prs.xsd" /t:code /language:cs /out:C:\SPrxy.cs /dconly
完整代码
(class generated by SvcUtils.exe)
[assembly: System.Runtime.Serialization.ContractNamespaceAttribute("http://service.a1.com/base1/2005/", ClrNamespace="service.a1.com.base1._2005")]
namespace service.a1.com.base1._2005
{
using System.Runtime.Serialization;
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="PersonType", Namespace="http://service.a1.com/base1/2005/")]
public partial class PersonType : object, System.Runtime.Serialization.IExtensibleDataObject
{
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
private string LastNameField;
private string FirstNameField;
public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true, EmitDefaultValue=false)]
public string LastName
{
get
{
return this.LastNameField;
}
set
{
this.LastNameField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)]
public string FirstName
{
get
{
return this.FirstNameField;
}
set
{
this.FirstNameField = value;
}
}
}
}
(code used for converting XML to object)
public static void convertToObject(string sFileName)
{
DataContractSerializer xs = new DataContractSerializer(typeof(PersonType));
PersonType Person = (PersonType)xs.ReadObject(new MemoryStream(File.ReadAllBytes(sFileName)));
}
(XSD)
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://service.a1.com/base1/2005/" xmlns:bse1="http://service.a1.com/base1/2005/" elementFormDefault="qualified">
<xs:complexType name="PersonType">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="LastName" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="FirstName" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="Person" type="bse1:PersonType"/>
</xs:schema>
(XML)
<?xml version="1.0" encoding="utf-8"?>
<pr:Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://service.a1.com/base1/2005/ Prs.xsd"
xmlns:pr="http://service.a1.com/base1/2005/">
<pr:LastName> Lane </pr:LastName>
<pr:FirstName> Fane </pr:FirstName>
</pr:Person>
我 运行 XSD.exe 在同一个 XSD 文件上。然后我可以使用 XmlSerializer.Deserialize()
.
将 XML 转换为对象
XSD 没有任何属性。我已经根据 XSD.
验证了 XML
请告诉我 Deserialize()
失败的原因。
您的 XSD 指定了不同的根元素名称和数据类型名称:
<xs:element name="Person" type="bse1:PersonType"/>
当 svcutil.exe
为该类型生成数据契约 类 时,它将 类型名称 放入数据契约而不是 根元素名称。这似乎是有意的,请参阅 Svcutil generates wrong Name property value in DataContractAttribute. Perhaps it does this since the contract type itself could be re-used anywhere in the object graph, and there's no data contract equivalent of XmlRoot
,当相关类型是文档的根元素时,它仅适用 。
作为解决方法,您有几个选择:
当 constructing the serializer:
时对预期的根元素名称进行硬编码
var xs = new DataContractSerializer(typeof(service.a1.com.base1._2005.PersonType), "Person", "http://service.a1.com/base1/2005/");
将 XML 预加载到 XDocument
中,并在构造序列化程序时使用实际的根元素名称:
var doc = XDocument.Load(sFileName);
service.a1.com.base1._2005.PersonType person;
var xs = new DataContractSerializer(typeof(service.a1.com.base1._2005.PersonType), doc.Root.Name.LocalName, "http://service.a1.com/base1/2005/");
using (var reader = doc.CreateReader())
{
person = (service.a1.com.base1._2005.PersonType)xs.ReadObject(reader);
}
或使用XmlSerializer
.
我运行SvcUtil.exe针对XSD文件生成class。然后尝试使用以下行从 XML 创建对象。我收到如下所示的错误。详细代码见下方
PersonType prs = (PersonType)xs.ReadObject(new MemoryStream(File.ReadAllBytes(sFileName)));
Error in line 3 position 58. Expecting element 'PersonType' from namespace 'http://service.a1.com/base1/2005/'.. Encountered 'Element' with name 'Person', namespace 'http://service.a1.com/base1/2005/'.
使用的命令
svcutil.exe" "C:\Temp\S1\UseXSDExe\UseXSDExe\Sample2\Prs.xsd" /t:code /language:cs /out:C:\SPrxy.cs /dconly
完整代码
(class generated by SvcUtils.exe)
[assembly: System.Runtime.Serialization.ContractNamespaceAttribute("http://service.a1.com/base1/2005/", ClrNamespace="service.a1.com.base1._2005")]
namespace service.a1.com.base1._2005
{
using System.Runtime.Serialization;
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name="PersonType", Namespace="http://service.a1.com/base1/2005/")]
public partial class PersonType : object, System.Runtime.Serialization.IExtensibleDataObject
{
private System.Runtime.Serialization.ExtensionDataObject extensionDataField;
private string LastNameField;
private string FirstNameField;
public System.Runtime.Serialization.ExtensionDataObject ExtensionData
{
get
{
return this.extensionDataField;
}
set
{
this.extensionDataField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute(IsRequired=true, EmitDefaultValue=false)]
public string LastName
{
get
{
return this.LastNameField;
}
set
{
this.LastNameField = value;
}
}
[System.Runtime.Serialization.DataMemberAttribute(EmitDefaultValue=false, Order=1)]
public string FirstName
{
get
{
return this.FirstNameField;
}
set
{
this.FirstNameField = value;
}
}
}
}
(code used for converting XML to object)
public static void convertToObject(string sFileName)
{
DataContractSerializer xs = new DataContractSerializer(typeof(PersonType));
PersonType Person = (PersonType)xs.ReadObject(new MemoryStream(File.ReadAllBytes(sFileName)));
}
(XSD)
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" targetNamespace="http://service.a1.com/base1/2005/" xmlns:bse1="http://service.a1.com/base1/2005/" elementFormDefault="qualified">
<xs:complexType name="PersonType">
<xs:sequence>
<xs:element minOccurs="1" maxOccurs="1" name="LastName" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="1" name="FirstName" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:element name="Person" type="bse1:PersonType"/>
</xs:schema>
(XML)
<?xml version="1.0" encoding="utf-8"?>
<pr:Person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://service.a1.com/base1/2005/ Prs.xsd"
xmlns:pr="http://service.a1.com/base1/2005/">
<pr:LastName> Lane </pr:LastName>
<pr:FirstName> Fane </pr:FirstName>
</pr:Person>
我 运行 XSD.exe 在同一个 XSD 文件上。然后我可以使用 XmlSerializer.Deserialize()
.
XSD 没有任何属性。我已经根据 XSD.
验证了 XML请告诉我 Deserialize()
失败的原因。
您的 XSD 指定了不同的根元素名称和数据类型名称:
<xs:element name="Person" type="bse1:PersonType"/>
当 svcutil.exe
为该类型生成数据契约 类 时,它将 类型名称 放入数据契约而不是 根元素名称。这似乎是有意的,请参阅 Svcutil generates wrong Name property value in DataContractAttribute. Perhaps it does this since the contract type itself could be re-used anywhere in the object graph, and there's no data contract equivalent of XmlRoot
,当相关类型是文档的根元素时,它仅适用 。
作为解决方法,您有几个选择:
当 constructing the serializer:
时对预期的根元素名称进行硬编码var xs = new DataContractSerializer(typeof(service.a1.com.base1._2005.PersonType), "Person", "http://service.a1.com/base1/2005/");
将 XML 预加载到
XDocument
中,并在构造序列化程序时使用实际的根元素名称:var doc = XDocument.Load(sFileName); service.a1.com.base1._2005.PersonType person; var xs = new DataContractSerializer(typeof(service.a1.com.base1._2005.PersonType), doc.Root.Name.LocalName, "http://service.a1.com/base1/2005/"); using (var reader = doc.CreateReader()) { person = (service.a1.com.base1._2005.PersonType)xs.ReadObject(reader); }
或使用
XmlSerializer
.