Подтвердить что ты не робот

WCF DataContract с свойствами readonly

Я пытаюсь вернуть сложный тип из метода службы в WCF. Я использую С# и .NET 4. Этот сложный тип должен быть инвариантным (так же, как и строки .net). Кроме того, служба только возвращает его и никогда не получает в качестве аргумента.

Если я пытаюсь определить только getters on properties, я получаю ошибку времени выполнения. Я думаю, это связано с тем, что сеттеры не приводят к сбою сериализации. Тем не менее, я думаю, что этот тип должен быть инвариантным.

Пример:

[DataContract]
class A 
{
   [DataMember]
   int ReadOnlyProperty {get; private set;}
}

Служба не загружается из-за проблемы с сериализацией.

Есть ли способ сделать readonly свойства в WCF DataContract? Возможно, заменив сериализатор? Если да, то как? Если нет, что бы вы предложили для этой проблемы?

Спасибо,
Асаф

4b9b3361

Ответ 1

Поле DataMember не может быть прочитано только потому, что wcf не сериализует объект as-is и каждый раз, когда beer deserialization start создает новый экземпляр объекта, используя конструктор по умолчанию. Диспетчеры используют сеттеры для установки значений полей после десериализации.

Но весь верхний текст может быть большой ошибкой:)

Чтобы сделать их реальными только для чтения, сделайте логику сервера, подтвердив эти значения полей.

Ответ 2

поместите [DataMember] в поле поддержки, вам не понадобится сеттер.

Ответ 3

Сделайте ваш сеттер общедоступным, чтобы удовлетворить сериализатор, но просто ничего не делайте в настройщике. Не "пурист", но делает это.

public string MyProperty 
{
    get {
        return this._myProperty
    }
    set {}
}

Ответ 4

Вы не можете сделать свойства readonly, однако вы можете приблизиться к readonly, сделав поля частью своего контракта, а не свойствами:

[DataContract]
public class A 
{
   public class A(){}
   public class A(int readonlyproperty){ _readonlyproperty = readonlyproperty}

   [DataMember(Name = "ReadOnlyProperty")]
   internal int _readonlyproperty;

   public int ReadOnlyProperty {
      get {return _readonlyproperty;}
      private set {_readonlyproperty = value;}
}

затем сделайте свои внутренние документы доступными в wcf:

[assembly: InternalsVisibleTo("System.Runtime.Serialization")]

Некоторые примеры использования этого в ваших интересах: wcf-and-datacontract-serialization-internals-and-tips

Ответ 5

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

Ответ 6

Собственно, вы можете сделать поля только для чтения сериализуемыми. Вам необходимо установить для свойства DataContractSerializerSettings значение "SerializeReadOnlyTypes" в "True", когда вы создаете DataContractSerializer, как показано ниже:

var xmlSerializer = new DataContractSerializer(typeof(yourTypeHere),  new DataContractSerializerSettings {SerializeReadOnlyTypes=true});

См. описание и подробности MSDN здесь: https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializersettings(v=vs.110).aspx

Ответ 7

WCF должен иметь возможность сериализовать/десериализовать свойство, что невозможно в частной собственности. Чтобы иметь свойство readonly (в сложном типе):

  • Украсить класс как [DataContract (IsReference = true)]
  • Украсить каждое свойство следующим образом: [DataMember]
  • Открытый Get, Внутренний Установить
    [DataContract(IsReference = true)]
    public class Format : ValueObject<Format>
    {
        [DataMember]
        public int Height { get; internal set; }
    }

Ответ 8

Вы пробовали сделать сеттер частным?

Что-то вроде:

public string MyProperty
{
get;
private set;
}