20

我试图从 WCF 中的服务方法返回一个复杂类型。我正在使用 C# 和 .NET 4。这种复杂类型是不变的(与 .net 字符串相同)。此外,服务只返回它,而不会将它作为参数接收。

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

例子:

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

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

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

谢谢,
阿萨夫

4

8 回答 8

16

放在[DataMember]后备场上,您将不需要二传手。

于 2010-03-22T19:02:25.180 回答
11

将您的设置器公开以满足序列化程序,但不要对设置器执行任何操作。不是“纯粹主义者”,但可以完成

public string MyProperty 
{
    get {
        return this._myProperty
    }
    set {}
}
于 2014-01-27T21:46:26.760 回答
5

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

但是所有大写的文字都可能是一个大错误:)

要使它们真正只读,请制作服务器逻辑,验证此字段值。

于 2010-03-24T15:45:32.250 回答
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

于 2014-10-02T12:12:13.160 回答
0

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

于 2014-08-24T22:15:49.800 回答
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

于 2015-04-20T14:33:44.940 回答
0

WCF 需要能够序列化/反序列化属性,而私有属性则无法做到这一点。拥有只读属性(在复杂类型中):

  • 将类装饰为 [DataContract(IsReference = true)]
  • 将每个/属性装饰为 [DataMember]
  • 公共获取,内部
    [DataContract(IsReference = true)]
    public class Format : ValueObject<Format>
    {
        [DataMember]
        public int Height { get; internal set; }
    }
于 2015-04-30T13:14:41.753 回答
-2

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

就像是:

public string MyProperty
{
get;
private set;
}
于 2010-03-22T19:01:08.793 回答