Значения службы WCF по умолчанию - PullRequest
10 голосов
/ 11 января 2010

У меня есть следующий класс контракта данных для моей Службы WCF:

[DataContract(Name = "MyClassDTO")]
public class MyClass
{
    private string name = "Default Name";

    [DataMember]
    public string Name
    {
        get { return name; }
        set { name = value; }
    }
}

Когда я использую функцию Add Service Reference для Visual Studio, чтобы сгенерировать ссылку на службу WCF, сгенерированный DataContract выглядит примерно так:

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name = "MyClassDTO", Namespace = "xxx")]
[System.SerializableAttribute()]
public partial class MyClassDTO : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged
{

    [System.Runtime.Serialization.OptionalFieldAttribute()]
    private string NameField;

    [System.Runtime.Serialization.DataMemberAttribute()]
    public string Name
    {
        get
        {
            return this.NameField;
        }
        set
        {
            if ((object.ReferenceEquals(this.NameField, value) != true))
            {
                this.NameField = value;
                this.RaisePropertyChanged("Name");
            }
        }
    }
}

Это означает, что значение по умолчанию «Имя по умолчанию» теряется и происходит следующее:

MyClassDTO mcdto = new MyClassDTO();
serviceClient.DoSomething(mcdto);


[OperationContract]
void DoSomething(MyClass mc){
   mc.Name //<--   == null    but I want it to be "Default Name"
}

Есть ли способ настроить контракт данных таким образом, чтобы определенное значение по умолчанию «Имя по умолчанию» не потерялось?

дополнительная информация : Я использую сервисную ссылку без повторного использования типов в ссылочных сборках, например на стороне клиента генерируется класс MyClass DTO и он не знает о классе сервера MyClass

Ответы [ 4 ]

3 голосов
/ 21 января 2010

Единственное возможное (но некрасивое и, следовательно, не очень удовлетворительное) решение, которое я обнаружил на этом этапе, - это использование атрибута OnDeserializing для установки значений по умолчанию в начале десериализации и использования установщика поля для определения, был ли значение должно быть действительно установлено.

   [DataContract(Name = "MyClassDTO")]
    public class MyClass
    {
        private string name;

        public MyClass()
        {
            Init();
        }

        [DataMember]
        public string Name
        {
            get{ return name; }
            set
            {
                if (!String.IsNullOrEmpty(value))
                {
                    name = value;
                }
            }
        }

        private void Init()
        {
            name = "Default Name";
        }

        [System.Runtime.Serialization.OnDeserializing]
        private void OnDeserializing(StreamingContext ctx)
        {
            Init();
        }
  }
2 голосов
/ 18 января 2010

Я не верю, что XML-схема позволяет описать значение элемента по умолчанию. Это означает, что для клиента вашей службы - это значение по умолчанию.

Кроме того, вы ничего не сделали для того, чтобы сообщить WCF, что вы хотите иметь значение по умолчанию, поэтому даже если бы был способ сообщить о своем намерении клиенту, факт заключается в том, что вы не сообщаете свое намерение.

2 голосов
/ 11 января 2010

Хммм .. Я думал , что есть некоторые вещи с [DefaultValue(...)], которые будут работать, но, очевидно, нет; Я немного сбит с толку, почему вы получаете null, хотя - поскольку вы не сообщили об этом по умолчанию, я бы ожидал, что "Default Name" попадет в вывод. Если у вас есть некоторый код по умолчанию (или ShouldSerialize* / *Specified), тогда вы можете попробовать:

[DataMember(EmitDefaultValue=true)]
public string Name {
    get { return name; }
    set { name = value; }
}

Но опять же - я не совсем уверен, почему вы видите null во-первых.

Я только что проверил это на чем-то, основанном на шаблоне WCF в VS2008, и он отлично работает:

using (var client = new Service1Client()) {
    var result = client.GetDataUsingDataContract();
    Console.Write(result.Name); // "Default Name"
}
1 голос
/ 20 января 2010

Во время десериализации будет выполняться логика 'set' вашего свойства, так что вы можете проверить на нулевое значение и установить желаемое значение по умолчанию в этой точке.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...