Я пишу веб-службу с использованием WCF.
Я создал контракты данных.
Я создал свой контракт службы (интерфейс). Я определил методы (параметры которых набраны как для контрактов данных).
Я реализовал контракт службы, создав класс службы.
Я разместил свою службу, используя файл svc и IIS.
Я попробовал свою службу, искал http: //localhost/myvirtdiriis/myservice.svc -> Служба была загружена, и появилась хорошая веб-страница, описывающая присутствие моей службы.
Я хотел посмотреть WSDL . Используя предоставленную ссылку, я вижу, что типы только определены, я вижу только определение типов (например,
), но ничего внутри (типы пустые).
Я закодировал простой клиент , вызов операции прошел успешно, но при возврате типа он пуст (внутренние поля имеют значения конструкции, а моя служба помещает туда некоторые значения), например, вызов операции, возвращающей тип, имеющий три строки, установленные метод контракта операции для «Hello», «Hello2» и «Hello3» возвращает тип, в котором для этих строк установлено значение «»
(значения конструкции, как если бы никаких изменений не произошло).
Что произошло?
Кажется, что сериализация не удалась.
Я предлагаю некоторые:
A1) Часть контракта на обслуживание:
[ServiceContract(Namespace = "http://opcfoundation.org/webservices/XMLDA/1.0/")]
public interface IOCXSService {
[OperationContract(Action = "http://opcfoundation.org/webservices/XMLDA/1.0/Browse")]
BrowseResponse Browse(BrowseRequest request);
...
}
A2) Реализация службы:
public class MyService : IOCXSService {
...
public BrowseResponse Browse(BrowseRequest request) {
...
}
...
}
B) Типы:
[DataContract(Namespace = "http://opcfoundation.org/webservices/XMLDA/1.0/", Name = "BrowseResponse")]
[System.ServiceModel.MessageContractAttribute(WrapperName = "BrowseResponse", WrapperNamespace = "http://opcfoundation.org/webservices/XMLDA/1.0/", IsWrapped = true)]
public class BrowseResponse {
[DataMember(Name = "BrowseResult", Order = 0)]
public OCXS.OCXSServiceLibrary.OPCXMLDA10.ReplyBase BrowseResult;
[DataMember(Name = "Elements", Order = 1)]
public BrowseElement[] Elements;
[DataMember(Name = "Errors", Order = 2)]
public OPCError[] Errors;
[DataMember(Name = "ContinuationPoint", Order = 3)]
public string ContinuationPoint;
[DataMember(Name = "MoreElements", Order = 4)]
public bool MoreElements;
public BrowseResponse() {
}
public BrowseResponse(OCXS.OCXSServiceLibrary.OPCXMLDA10.ReplyBase BrowseResult, BrowseElement[] Elements, OPCError[] Errors, string ContinuationPoint, bool MoreElements) {
this.BrowseResult = BrowseResult;
this.Elements = Elements;
this.Errors = Errors;
this.ContinuationPoint = ContinuationPoint;
this.MoreElements = MoreElements;
}
[DataContract(Namespace = "http://opcfoundation.org/webservices/XMLDA/1.0/", Name = "ReplyBase")]
public class ReplyBase : System.ComponentModel.INotifyPropertyChanged {
private System.DateTime rcvTimeField;
private System.DateTime replyTimeField;
private string clientRequestHandleField;
private string revisedLocaleIDField;
private serverState serverStateField;
[DataMember(Name = "RcvTime", Order = 0)]
public System.DateTime RcvTime {
get {
return this.rcvTimeField;
}
set {
this.rcvTimeField = value;
this.RaisePropertyChanged("RcvTime");
}
}
[DataMember(Name = "ReplyTime", Order = 1)]
public System.DateTime ReplyTime {
get {
return this.replyTimeField;
}
set {
this.replyTimeField = value;
this.RaisePropertyChanged("ReplyTime");
}
}
[DataMember(Name = "ClientRequestHandle", Order = 2)]
public string ClientRequestHandle {
get {
return this.clientRequestHandleField;
}
set {
this.clientRequestHandleField = value;
this.RaisePropertyChanged("ClientRequestHandle");
}
}
[DataMember(Name = "RevisedLocaleID", Order = 3)]
public string RevisedLocaleID {
get {
return this.revisedLocaleIDField;
}
set {
this.revisedLocaleIDField = value;
this.RaisePropertyChanged("RevisedLocaleID");
}
}
[DataMember(Name = "ServerState", Order = 4)]
public serverState ServerState {
get {
return this.serverStateField;
}
set {
this.serverStateField = value;
this.RaisePropertyChanged("ServerState");
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
[DataContract(Namespace = "http://opcfoundation.org/webservices/XMLDA/1.0/", Name = "BrowseElement")]
public class BrowseElement : INotifyPropertyChanged {
private ItemProperty[] propertiesField;
private string nameField;
private string itemPathField;
private string itemNameField;
private bool isItemField;
private bool hasChildrenField;
[DataMember(Name = "Properties", Order = 0)]
public ItemProperty[] Properties {
get {
return this.propertiesField;
}
set {
this.propertiesField = value;
this.RaisePropertyChanged("Properties");
}
}
[DataMember(Name = "Name", Order = 1)]
public string Name {
get {
return this.nameField;
}
set {
this.nameField = value;
this.RaisePropertyChanged("Name");
}
}
[DataMember(Name = "ItemPath", Order = 2)]
public string ItemPath {
get {
return this.itemPathField;
}
set {
this.itemPathField = value;
this.RaisePropertyChanged("ItemPath");
}
}
[DataMember(Name = "ItemName", Order = 3)]
public string ItemName {
get {
return this.itemNameField;
}
set {
this.itemNameField = value;
this.RaisePropertyChanged("ItemName");
}
}
[DataMember(Name = "IsItem", Order = 4)]
public bool IsItem {
get {
return this.isItemField;
}
set {
this.isItemField = value;
this.RaisePropertyChanged("IsItem");
}
}
[DataMember(Name = "HasChildren", Order = 5)]
public bool HasChildren {
get {
return this.hasChildrenField;
}
set {
this.hasChildrenField = value;
this.RaisePropertyChanged("HasChildren");
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
[DataContract(Namespace = "http://opcfoundation.org/webservices/XMLDA/1.0/", Name = "OPCError")]
public class OPCError : System.ComponentModel.INotifyPropertyChanged {
private string textField;
private System.Xml.XmlQualifiedName idField;
[DataMember(Name = "Text", Order = 0)]
public string Text {
get {
return this.textField;
}
set {
this.textField = value;
this.RaisePropertyChanged("Text");
}
}
[DataMember(Name = "ID", Order = 1)]
public System.Xml.XmlQualifiedName ID {
get {
return this.idField;
}
set {
this.idField = value;
this.RaisePropertyChanged("ID");
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
C) WSDL (часть, касающаяся определений типов)
-
Вышеупомянутая часть включена сюда:
-
-
-
-
ПРИМЕЧАНИЕ:
Если я удалю атрибут MessageContract
из BrowseResponse
и BrowseRequest
(оба удалены, иначе время выполнения становится сумасшедшим), проблема не исчезнет ....
Это действительно проблема с контрактами на сообщения ???
МОЖЕТ БЫТЬ РЕШЕНИЕМ
Хорошо, все, может быть, я увижу свет ...
Если я удалю все атрибуты DataContract
(s) и ServiceContract
(s), пространство имен и имена (всегда без MessageContract
(s)), все будет работать. Ну, у меня есть wsdl и типы, но он работал даже с ними (но всегда без MessageContract
(s)).
Вот почему (я хотел бы получить от вас подтверждение):
Указанное мной пространство имен: http://opcfoundation.org/webservices/XMLDA/1.0/ не простое имя, ну вот вы можете найти определения WSDL для моих операций и типов (уже определенных). Мой svc не генерирует полные определения WSDL с типами, ПОТОМУ ЧТО ОН УЖЕ ИХ ОПРЕДЕЛЕН в указанном мной пространстве имен !!!
Что вы думаете об этом?