与SvcUtils.exe一起使用时,DataContractSerializer.ReadObject()无法创建对象



我针对XSD文件运行SvcUtil.exe以生成类。然后尝试使用以下行从XML创建Object。我得到的错误如下所示。请参阅下面的详细代码。

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:TempS1UseXSDExeUseXSDExeSample2Prs.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文件上运行了XSD.exe。然后,我能够使用XmlSerializer.Deserialize()将XML转换为Object。

XSD没有任何属性。我已经根据XSD验证了XML。

请告诉我Deserialize()失败的原因。

XSD指定了不同的根元素名称和数据类型名称:

 <xs:element name="Person" type="bse1:PersonType"/> 

svcutil.exe为该类型生成数据协定类时,它将类型名称放入数据协定中,而不是根元素名称/em>。

作为一种变通方法,您有两个选项:

  1. 构造序列化程序时对所需的根元素名称进行硬编码:

        var xs = new DataContractSerializer(typeof(service.a1.com.base1._2005.PersonType), "Person", "http://service.a1.com/base1/2005/");
    
  2. 将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);
        }
    
  3. 或者使用XmlSerializer

最新更新