具有只读属性的WCF DataContract

时间:2010-03-22 18:54:50

标签: .net wcf .net-4.0 datacontract

我正在尝试从WCF中的服务方法返回一个复杂类型。我正在使用C#和.NET 4.这种复杂类型意味着不变(与.net字符串相同)。此外,该服务仅返回它,并且从不作为参数接收它。

如果我尝试仅在属性上定义getter,则会出现运行时错误。我想这是因为没有setter导致序列化失败。不过,我认为这种类型应该是不变的。

示例:

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

由于序列化问题,服务无法加载。

有没有办法在WCF DataContract上创建只读属性?也许通过更换序列化器?如果是这样,怎么样?如果没有,你会对这个问题提出什么建议?

谢谢,
阿萨夫

8 个答案:

答案 0 :(得分:14)

[DataMember]放在后备字段上,您将不需要设置器。

答案 1 :(得分:9)

让你的setter公开以满足序列化程序,但只是不对setter做任何事情。不是“纯粹主义者”,而是完成它

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

答案 2 :(得分:4)

您不能将属性设置为只读,但是通过使字段成为合同的一部分而不是属性,您可以接近只读:

[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

答案 3 :(得分:2)

DataMember字段不能只读,因为wcf不按原样序列化对象,每次反序列化开始时都会使用默认构造函数创建新的对象实例。调度程序使用setter在反序列化后设置字段值。

但是所有上层文字都是一个大错误:)

要使它们真正只读,请创建服务器逻辑,验证thiss字段值。

答案 4 :(得分:0)

正如其他人所说,WCF需要吸气剂和制定者。 话虽这么说,我带着同样的问题来到这里,答案让我问为什么我需要一个只读属性。如果使用MVVM模式,则服务返回的类是Model,因此不应直接由UI公开。您可以轻松地将ViewModel设置为只读。或者,您可以使用非UI目标的Facade类。

答案 5 :(得分:0)

实际上,您可以将只读字段设置为可序列化。在构造DataContractSerializer时,需要将DataContractSerializerSettings的'SerializeReadOnlyTypes'属性设置为'True',如下所示:

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

答案 6 :(得分:0)

WCF需要能够序列化/反序列化属性,而私有属性是不可能的。拥有只读属性(在复杂类型中):

  • 将类装饰为[DataContract(IsReference = true)]
  • 将每个/属性装饰为[DataMember]
  • 公开获取,内部设置
    [DataContract(IsReference = true)]
    public class Format : ValueObject<Format>
    {
        [DataMember]
        public int Height { get; internal set; }
    }

答案 7 :(得分:-1)

您是否尝试过将setter设为私有?

类似的东西:

public string MyProperty
{
get;
private set;
}