これが状況です。私は 2 つの WCF サービスを持っています。1 つは BizTalk サービスで、もう 1 つはデータ リポジトリのクエリに使用される通常の WCF サービスです。これらの両方のサービスにサービス参照が追加されたテスト アプリケーションがあります。これらの両方のサービスとの間でデータをやり取りするために HL7v3 スキーマを使用しています。
BizTalk WCF プロキシ クラスは を使用して生成されるようですSystem.Xml.Serialization
が、他の非 BizTalk プロキシは を使用してすべてに遭遇しますSystem.Runtime.Serialization
。
BizTalk プロキシ クラスを使用すると正常に逆シリアル化できますが、他のクラスを使用すると逆シリアル化できません。そうしようとしているときに発生するエラーは次のとおりです。
「targetNamespace パラメーター 'urn:hl7-org:v3' は、スキーマの targetNamespace ' http://schemas.datacontract.org/2004/07/ 'と同じ値である必要があります。」
Reference.cs ファイルを見ると、次の理由から、このエラーは理にかなっています。
[System.Runtime.Serialization.DataContractAttribute(Name="RCMR_IN000029UV01MCCI_MT000100UV01Message", Namespace="http://schemas.datacontract.org/2004/07/")]
そのため、調査を行ったところ、Service/Method 宣言に属性を追加することで、WCF サービスに DataContract ではなく XmlSerializer を強制的に使用させることができることがわかりました。
[XmlSerializerFormat(Style=System.ServiceModel.OperationFormatStyle.Document)]
そのとき、Reference.cs で System.XmlSerialization が使用され、2 つの Reference.cs ファイルが非常に似ていることに気付きました。
さて、最終的な問題は次のとおりです。
DataContract ではなく XMLSerializer を切り替えた後、実際には Proxy クラス (HL7v3 RCMR_IN000029UV01) のインスタンスを生成できません。これは、プロキシ クラスが生成されるときにルート ノード (最終的にオブジェクト タイプになる) に遭遇しないためです。したがって、逆シリアル化 (または単にインスタンスを作成しようとする) に関しては、たとえばXmlSerializer pXmlSerializer = new XmlSerializer(RCMR_IN000029UV01);
、RCMR_IN000029UV01 がどこにも存在しないため、実行できません。
サービス自体は非常に単純です。
[ServiceContract (Namespace="urn:hl7-org:v3")]
[XmlSerializerFormat(Style = System.ServiceModel.OperationFormatStyle.Document)]
public interface IRequestCDAService
{
[OperationContract]
string GetData(RCMR_IN000029UV01 query);
[OperationContract]
string GetDataByXML(XmlDocument queryXml);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
}
ただし、私はまだ WCF サービスにあまり慣れていないため、属性などに関して不足しているものがあるかどうかはわかりません。
唯一の実際の違いは、プロキシ クラスにスキーマのルート ノードの実際のコンストラクターがないことです。BizTalk サービスのプロキシ クラスは次のようになります。
public partial class RCMR_IN000002UV01 : RCMR_IN000002UV01MCCI_MT000100UV01Message {
private string iTSVersionField;
public RCMR_IN000002UV01() {
this.iTSVersionField = "XML_1.0";
}
/// <remarks/>
[System.Xml.Serialization.XmlAttributeAttribute()]
public string ITSVersion {
get {
return this.iTSVersionField;
}
set {
this.iTSVersionField = value;
this.RaisePropertyChanged("ITSVersion");
}
}
}
しかし、他の (非 BizTalk) サービスの reference.cs を見ると、
public RCMR_IN000029UV01() {
this.iTSVersionField = "XML_1.0";
}
がクラス定義にありません。私は何が欠けていますか?
編集: 言及するのを忘れていました。Web サービスは、xsd.exe を使用して HL7v3 RCMR_IN000029UV01 スキーマから生成されたクラスファイルに基づいて、これらの RCMR オブジェクトを公開しています。つまり、自分で作ったクラスではありません。