只读字段的WCF DataMember属性?

只读字段的WCF DataMember属性?,wcf,datacontract,datamember,Wcf,Datacontract,Datamember,我试图创建一个具有只读Id字段的类,但是当对象通过WCF服务器时,我在保留值时遇到问题 我无法在公共属性上设置[DataMember]属性,因为没有set方法,如果可能,我希望保持这种方式,因为我不希望通过外部方式更改此值。我无法在私有字段上设置[DataMember]属性,因为它在部分信任环境中引发错误 public class MyClass { private int _id; public int Id { get { return _id;

我试图创建一个具有只读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; }
    }
}

有没有办法在通过WCF服务器时维护Id字段的值而不公开我的属性?

没有。数据成员必须具有getter和setter才能序列化。服务负责验证客户机上的Id是否未更改。

一般来说,您的数据协定类应该是非常轻量级的数据传输对象,没有任何逻辑或更深层次的含义。只是用来在云端传递数据的容器。它们应该是公共类,只有一组公共读写属性。在业务逻辑类中,您应该将它们转换为一些内部业务实体,并在传输数据时执行相反的操作

这将数据传输模型从任何内部实体模型中分离出来,并确保最佳的可维护性,允许您避免遇到诸如OO设计问题与WCF操作行为冲突的问题

对于非常小的项目,保留单独模型的开销可能不值得。可以帮助减少所需的体力劳动

说到你的具体情况,我不确定我是否完全理解问题陈述。是否不希望修改某些字段?但是这个字段只是数据模型的一部分-数据模型的部分永远不会被“修改”-没有“旧”数据,只有客户机生成的数据。您的客户机代码只是向服务器发送一个数据对象。如果服务器不关心类中的一个成员,它应该忽略它

这不像服务器上存在数据契约对象的指令,并等待客户端对其进行操作。在这种情况下,只读字段在概念上可能有意义,但在WCF中并非如此。客户机只是组成一个对象并将其发送到服务器。如果不希望服务器侦听某些数据,请不要将其添加到数据模型中,或者(如果有时需要,仅针对特定用户或类似用户)让服务器在不需要时忽略这些数据。

您可以这样做:

public int Id
{
     get;
     private set;
}
这将使反序列化程序保持愉快,同时不允许人们实际设置ID值。您必须在构造函数或其他属性的setter中设置它


不过,我确实同意桑德斯的观点,因为您的DTO应该是一个愚蠢的容器。

让我看看是否有这条直线。。。您建议每个对象应该有两部分:用于向WCF服务器发送/接收数据的DataTransfer(DataContract)类和包含业务逻辑、INotifyPropertyChanged、功能等的实际类本身?是和否。数据传输对象实际上不需要一对一映射到任何业务逻辑对象。例如,我可能有一个大型而复杂的Employee业务对象,但在我的各种WCF操作中,我只公开与特定操作相关的数据。例如,UpdateContactInfo(Guid employeeID,ContactInfo info)将仅携带联系人信息,而它可能仍然是我的员工业务对象的一部分。对于小型场景,数据传输对象和业务对象往往几乎相同,只是没有任何“不需要的”字段(例如密码散列):如果您有一个私有方法,它不应该抛出错误。您可以在注释中看到:DataContract不关心方法的可见性。