Атрибут WCF DataMember для полей только для чтения? - PullRequest
7 голосов
/ 29 сентября 2010

Я пытаюсь создать класс с полем Id, доступным только для чтения, однако у меня возникают проблемы с сохранением значения, когда объект проходит через сервер WCF.

Я не могу установить атрибут [DataMember]публичное свойство, так как нет метода set, и я хотел бы сохранить его, если это возможно, поскольку я не хочу, чтобы это значение изменялось внешними средствами.Я не могу установить атрибут [DataMember] в приватном поле, так как он выдает ошибку в средах с частичным доверием.

public class MyClass
{
    private int _id;

    public int Id 
    { 
        get { return _id; } 
    }

    private string _otherProperties;

    [DataMember]
    public string OtherProperties
    {
        get { return _otherProperties; } 
        set { _otherProperties = value; }
    }
}

Есть ли способ сохранить значение поля Id при прохождении через сервер WCF безсделать мою собственность публичной?

Ответы [ 3 ]

8 голосов
/ 29 сентября 2010

Вы можете сделать это:

public int Id
{
     get;
     private set;
}

Это будет радовать десериализатор, не позволяя людям фактически установить значение идентификатора. Вам придется установить его в конструкторе или в установщике другого свойства.

Однако я согласен с Сандерсом в том, что ваш DTO должен быть тупым контейнером.

7 голосов
/ 29 сентября 2010

Вообще говоря, ваши классы контрактов данных должны быть очень легкими объектами передачи данных без какой-либо логики или более глубокого значения, прикрепленного к ним. Просто контейнеры для передачи данных через облако. Это должны быть открытые классы, имеющие только набор открытых свойств для чтения и записи. В ваших классах бизнес-логики вы должны конвертировать их в некоторые внутренние бизнес-объекты и делать обратное при передаче данных.

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

С очень маленькими проектами затраты на сохранение отдельной модели могут не стоить этого. AutoMapper может помочь в минимизации ручного труда.

Говоря о вашем конкретном сценарии, я не уверен, что точно понимаю формулировку проблемы. Вы не хотите, чтобы какое-то поле было изменено? Но это поле является лишь частью модели данных - части модели данных никогда не «модифицируются» - здесь нет «старых» данных, только данные, которые составляет ваш клиент. Ваш клиентский код просто отправляет объект данных на сервер. Если сервер не заботится об одном члене класса, он должен просто игнорировать его.

Не похоже, что экземпляры объектов контракта данных существуют на сервере и ждут, когда клиенты манипулируют ими. Поле «только для чтения» может концептуально иметь смысл в таком сценарии, но это не так с WCF. Клиент просто составляет объект и отправляет его на сервер. Если вы не хотите, чтобы сервер прослушивал некоторые данные, либо не добавляйте их в модель данных, либо (если, возможно, это иногда требуется, только для определенных пользователей или тому подобное), заставьте сервер игнорировать их, когда это нежелательно.

1 голос
/ 29 сентября 2010

Нет. Член данных должен иметь геттер и сеттер, чтобы быть сериализуемым. Служба несет ответственность за проверку того, что идентификатор клиента не был изменен.

...