2016-08-03 14 views
1

私はxmlserializationを使用してwcfサービスを持っています。 このようSOAPUIに見えるいくつかのクラスがあります:IXmlSerializable実装が正しくない場合のWCFサービスxsd

 <MyClass> 
     <propertyA>?</propertyA> 
     <propertyB>?</propertyB> 
    </MyClass> 

私はそれにIXmlSerializableインターフェイスを実装する必要がありました。 それをやった後、クラスがSOAPUIに奇妙な構造を有する:

 <MyClass> 
     <xs:schema> 
      <!--Ignoring type [{http://www.w3.org/2001/XMLSchema}schema]--> 
     </xs:schema> 
     <!--You may enter ANY elements at this point--> 
    </MyClass> 

それはGetSchemaメソッドの次の実装の結果である可能性がありますか?以下は

public XmlSchema GetSchema() 
    { 
     return null; 
    } 

サービスのWSDLからのMyClassについてのセクションです:

<xs:element name="MyClass" form="unqualified" maxOccurs="1" minOccurs="0"> 
    <xs:complexType> 
    <xs:sequence> 
     <xs:element ref="xs:schema"/> 
     <xs:any/> 
    </xs:sequence> 
    </xs:complexType> 
</xs:element> 

答えて

1

GetSchema()は常にnullを返す必要があります。 Proper way to implement IXmlSerializable?を参照してください。

代わりに[XmlSchemaProvider(string methodName)]をクラスに追加し、XMLスキーマを返す静的メソッドと、その型のスキーマを指定するXmlQualifiedName(または匿名型の場合はXmlSchemaType)を実装する必要があります。私はと期待されるスキーマが埋め込まれている

ここ
[XmlSchemaProvider("GetSchemaMethod")] 
[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/Question38741035")] 
public class MyClass : IXmlSerializable 
{ 
    public string PropertyA { get; set; } 

    public decimal PropertyB { get; set; } 

    const string XmlNamespace = "http://schemas.datacontract.org/2004/07/Question38741035"; 

    // This is the method named by the XmlSchemaProviderAttribute applied to the type. 
    public static XmlQualifiedName GetSchemaMethod(XmlSchemaSet xs) 
    { 
     string schema = @"<?xml version=""1.0"" encoding=""utf-16""?> 
<xs:schema 
    xmlns:tns=""http://schemas.datacontract.org/2004/07/Question38741035"" 
    elementFormDefault=""qualified"" 
    targetNamespace=""http://schemas.datacontract.org/2004/07/Question38741035"" 
    xmlns:xs=""http://www.w3.org/2001/XMLSchema""> 
    <xs:complexType name=""MyClass""> 
    <xs:sequence> 
     <xs:element minOccurs=""0"" name=""PropertyA"" nillable=""true"" type=""xs:string"" /> 
     <xs:element minOccurs=""0"" name=""PropertyB"" type=""xs:decimal"" /> 
    </xs:sequence> 
    </xs:complexType> 
    <xs:element name=""MyClass"" nillable=""true"" type=""tns:MyClass"" /> 
</xs:schema>"; 

     using (var textReader = new StringReader(schema)) 
     using (var schemaSetReader = System.Xml.XmlReader.Create(textReader)) 
     { 
      xs.Add(XmlNamespace, schemaSetReader); 
     } 
     return new XmlQualifiedName("MyClass", XmlNamespace); 
    } 

    #region IXmlSerializable Members 

    public System.Xml.Schema.XmlSchema GetSchema() 
    { 
     return null; 
    } 

    public void ReadXml(System.Xml.XmlReader reader) 
    { 
     if (reader.IsEmptyElement) 
     { 
      reader.Read(); 
      return; 
     } 

     var node = (XElement)XNode.ReadFrom(reader); 
     if (node != null) 
     { 
      var ns = (XNamespace)XmlNamespace; 

      PropertyA = (string)node.Element(ns + "PropertyA"); 
      PropertyB = (decimal)node.Element(ns + "PropertyB"); 
     } 
    } 

    public void WriteXml(System.Xml.XmlWriter writer) 
    { 
     if (PropertyA != null) 
      writer.WriteElementString("PropertyA", XmlNamespace, PropertyA); 
     writer.WriteStartElement("PropertyB", XmlNamespace); 
     writer.WriteValue(PropertyB); 
     writer.WriteEndElement(); 
    } 

    #endregion 
} 

[DataContract(Namespace = "http://schemas.datacontract.org/2004/07/Question38741035")] 
[XmlRoot(Namespace = "http://schemas.datacontract.org/2004/07/Question38741035")] 
public class MyClass 
{ 
    [DataMember] 
    public string PropertyA { get; set; } 

    [DataMember] 
    public decimal PropertyB { get; set; } 
} 

次にタイプのごIXmlSerializable再実装は次のようになります。あなたの元の型がどのように見える場合例えば

、型の中の文字列リテラル。また、ディスクから読み込んだり、リフレクションで構築したりすることもできます。

関連する問題