99

我有一些由于服务方法而传递的类,并且该类具有仅获取属性:

[DataContract]
public class ErrorBase
{
  [DataMember]
  public virtual string Message { get { return ""; } }
}

我在服务方面遇到了一个例外:

System.Runtime.Serialization.InvalidDataContractException:“MyNamespace.ErrorBase”类型中的属性“Message”没有设置方法。

我必须将此属性作为唯一的吸气剂,我不能允许用户为其分配值。我可以使用任何解决方法吗?或者我错过了一些额外的属性?

4

9 回答 9

109

给 Message 一个公共的 getter 但受保护的 setter,这样只有子类(和 DataContractSerializer,因为它作弊 :) 可以修改该值。

于 2010-02-24T02:34:34.570 回答
13

即使您不需要更新值,WCFSerializer 也会使用 setter 来反序列化对象(并重新设置值)。

这就是你所追求的: WCF DataContracts

于 2010-02-24T02:31:43.607 回答
11
[DataMember(Name = "PropertyName")]
public string PropertyName
{
    get
    {
        return "";
    }
    private set
    { }
}
于 2012-08-06T11:21:40.173 回答
5

难道你不能只有一个“无所事事”的二传手吗?

[DataContract]
public class ErrorBase
{
  [DataMember]
  public virtual string Message 
  {
      get { return ""; } 
      set { }
  }
}

还是 DataContract 序列化程序也讨厌?

于 2010-02-24T06:05:08.510 回答
5

如果你只有一个 getter,为什么你需要序列化属性。似乎您可以删除只读属性的 DataMember 属性,而序列化程序只会忽略该属性。

于 2016-09-23T21:18:25.850 回答
2

具有 DataMember 属性的属性始终需要设置。您应该在客户端应用程序上重新编写类似对象,因为始终可以为 DataContract 成员分配值。

于 2010-02-24T06:16:46.230 回答
2

我在使用 ASP.NET MVC 时遇到了这个问题,我想使用 DataContractSerializer 以便能够控制 JSON 输出中项目的名称。最终我将序列化器切换到 JSON.NET,它支持没有设置器的属性(DataContractSerializer 不支持)和属性名称控制(ASP.NET MVC 中的内置 JSON 序列化器不支持)[JsonProperty(PropertyName = "myName")]

于 2011-09-13T09:58:42.980 回答
2

如果这是一个可行的选择,那么不要将其ErrorBase作为基类,而是将其定义如下:

    public interface IError
    {
        string Message
        {
            [OperationContract]
            get;

            // leave unattributed
            set;
        }
    }

现在,即使存在 setter,客户端也无法通过 WCF 通道访问它,因此它就像是私有的。

于 2012-05-25T22:32:17.680 回答
1

如果您的序列化程序是类型DataContractJsonSerializer(或任何DataContractSerializer),您也可以DataContractSerializerSettings在构造函数中使用,并将SerializeReadOnlyTypes属性设置为 true。

于 2020-05-28T13:39:17.267 回答