Вот такая ситуация. У меня есть две службы WCF, одна - это служба BizTalk, другая - обычная служба 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/")]
Итак, я провел небольшое исследование и обнаружил, что вы можете заставить службу WCF использовать XmlSerializer, а не DataContract, добавив атрибут в объявления службы / метода:
[XmlSerializerFormat(Style=System.ServiceModel.OperationFormatStyle.Document)]
Тогда я заметил в Reference.cs, что теперь используется System.XmlSerialization, и 2 файла Reference.cs начинают выглядеть очень похожими.
Итак, последняя проблема:
После переключения XMLSerializer вместо DataContract я не могу фактически сгенерировать экземпляр класса 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");
}
}
}
Но когда вы посмотрите на reference.cs для другой службы (не BizTalk),
public RCMR_IN000029UV01() {
this.iTSVersionField = "XML_1.0";
}
отсутствует в определении класса. Что мне не хватает?
РЕДАКТИРОВАТЬ: я забыл упомянуть. Веб-сервис предоставляет эти объекты RCMR на основе файла классов, созданного из схемы HL7v3 RCMR_IN000029UV01 с использованием xsd.exe. Другими словами, это не класс, который я создал сам.