0

私はWCFの初心者です。そのための WCF サービスとクライアントを開発しました。サービス メソッドは、カスタム XML シリアライザーを使用するカスタム データを取得します。この場合、コントラクトメソッドは次のようにマークする必要があります[XmlSerializerFormat]

[ServiceContract]
[XmlSerializerFormat]
public interface ITSService
{
    [OperationContract]
    [XmlSerializerFormat]
    ProtocolDocument GetReferenceData(string referenceType, SerializableDictionary<string, string> args);

ProtocolDocument実装IXmlSerializable:

[XmlRoot("protocol", Namespace = Protocol30Namespace)]
[Type(Name = "protocol", Namespace = Protocol30Namespace)]
public class ProtocolDocument : ProtocolElement, ICloneable, IXmlSerializable

VS 2010 はwsHttpBindingデフォルトで選択します。セキュリティは必要ないのでオフにしました。

サービス構成は次のとおりです。

<services>
   <service name="MyNamespace.TSService" 
            behaviorConfiguration="MyNamespace.TSServiceBehavior">
      <host>
         <baseAddresses>
            <add baseAddress = "http://localhost:51944/TSService.svc" />
         </baseAddresses>
      </host>
      <endpoint 
          address="" 
          binding="wsHttpBinding" 
          bindingConfiguration="nonSecurityWSHttpBinding"
          contract="MyNamespace.ITSService">
         <identity>
            <dns value="localhost"/>
         </identity>
      </endpoint>
      <endpoint 
          address="mex" 
          binding="mexHttpBinding" 
          contract="IMetadataExchange"/>
   </service>
</services>
<behaviors>
   <serviceBehaviors>
      <behavior name="MyNamespace.TSServiceBehavior">
         <serviceMetadata httpGetEnabled="true" />
         <serviceDebug includeExceptionDetailInFaults="true" />
      </behavior>
   </serviceBehaviors>
</behaviors>
<bindings>
   <wsHttpBinding>
      <binding name="nonSecurityWSHttpBinding">
         <security mode="None">
            <transport clientCredentialType="None"/>
         </security>
      </binding>
   </wsHttpBinding>
</bindings>

次に、このサービスのクライアントを生成しましたが、結果を逆シリアル化できませんでした。Fiddler によると、SOAP はシリアル化されたデータをGetReferenceDataResultandにラップしGetReferenceDataResponseます。

 <s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing">
  <s:Header>
    <a:Action s:mustUnderstand="1">http://tempuri.org/ITourSystemService/GetReferenceDataResponse</a:Action>
    <a:RelatesTo>urn:uuid:3d7f6dc0-4961-4bc5-b1fc-c9997af9fbd4</a:RelatesTo>
  </s:Header>
  <s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    <GetReferenceDataResponse xmlns="http://tempuri.org/">
      <GetReferenceDataResult>
          <header version="3.0" language="Russian"/>
          <references/>
      </GetReferenceDataResult>
    </GetReferenceDataResponse>
  </s:Body>
</s:Envelope>

しかし、ルート要素がありません! 私は何をすべきか?

PS シリアライゼーション実装:

 void IXmlSerializable.ReadXml(XmlReader reader)
{
    var serializer = new ProtocolDocumentXmlSerializer();
    serializer.Deserialize(this, reader);
}

void IXmlSerializable.WriteXml(XmlWriter writer)
{
    //
    // Serialize everything except the root element, because it was already written by .NET XML-serialization mechanism
    var xmlSerializationFlags = XmlSerializationFlags.All & ~XmlSerializationFlags.IncludeRootElement;

    var serializer = new ProtocolDocumentXmlSerializer();
    serializer.Serialize(this, writer, xmlSerializationFlags);
}

Xml シリアル化はうまく機能します。すでに使用されています。私のWCF構成に問題があると思います。

4

1 に答える 1

0

WriteXmlメソッドでルート要素を無視するように明示的に指示したようです-それがルート要素がない理由です

var xmlSerializationFlags = XmlSerializationFlags.All & ~XmlSerializationFlags.IncludeRootElement;

デシリアライズを機能させることができない場合は、クライアントのコントラクトのリターンタイプとしてメッセージを使用して常にXMLレベルで作業し、メッセージに対してGetReaderAtBodyを呼び出し、データをXElementにロードし、LINQtoXMLを使用してXMLをオブジェクトに変換できます。クライアント側で作業する

于 2012-05-15T11:38:11.627 に答える