Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 具有只读属性的WCF DataContract_.net_Wcf_.net 4.0_Datacontract - Fatal编程技术网

.net 具有只读属性的WCF DataContract

.net 具有只读属性的WCF DataContract,.net,wcf,.net-4.0,datacontract,.net,Wcf,.net 4.0,Datacontract,我试图从WCF中的服务方法返回复杂类型。我正在使用C#和.NET4。这个复杂类型是不变的(与.net字符串的方式相同)。此外,服务只返回它,从不将其作为参数接收 如果我试图只在属性上定义getter,就会出现运行时错误。我想这是因为没有setter会导致序列化失败。不过,我认为这种类型应该是不变的 例如: [DataContract] class A { [DataMember] int ReadOnlyProperty {get; private set;} } 由于序列化问题

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

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

例如:

[DataContract]
class A 
{
   [DataMember]
   int ReadOnlyProperty {get; private set;}
}
由于序列化问题,无法加载服务

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

谢谢,

尽快

你有没有试过让二传员保密

比如:

public string MyProperty
{
get;
private set;
}

[DataMember]
放在backing字段上,您将不需要setter。

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

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


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

将setter公开以满足序列化程序的要求,但不要在setter上执行任何操作。不是“纯粹主义者”,而是完成它

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

正如其他人所说,WCF需要能手和能手。
尽管如此,我还是带着同样的问题来到这里,答案让我问自己为什么需要只读属性。如果使用MVVM模式,则服务返回的类就是模型,因此不应直接由UI公开。您可以轻松地将ViewModel设置为只读。或者,您可以使用非UI目标的facade类。

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

[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")]

一些示例介绍了如何利用此功能:

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

var xmlSerializer = new DataContractSerializer(typeof(yourTypeHere),  new DataContractSerializerSettings {SerializeReadOnlyTypes=true});

请参见此处的MSDN说明和详细信息:

WCF需要能够序列化/反序列化属性,这在私有属性中是不可能的。要具有只读属性(在复杂类型中),请执行以下操作:

  • 将类修饰为[DataContract(IsReference=true)]
  • 将每个/每个属性装饰为[DataMember]
  • 公共获取,内部设置
[DataContract(IsReference=true)]
公共类格式:ValueObject
{
[数据成员]
公共整数高度{get;内部集合;}
}

是的。这正是我的问题,所以这就解决了?或者这就是你想要的?它不起作用。如果我将MyProperty设置为[DataMember],我会从序列化中得到一个运行时错误。一旦服务加载,它就会发生,甚至在客户端操作期间也不会发生。@AsafR:正确,似乎必须为所有字段设置get/set,序列化/反序列化才能工作。从我所读到的每件事来看,我认为没有办法解决这个问题:(如果你想在上面的答案中给出你的结论,我很乐意让它成为公认的答案。但它不会是只读的,也不会表示它应该是只读的。它永远不会是只读的。通过网络传输的Datacontract只是一个XML。你不能使一段XML成为只读的。你不能让另一端的人成为只读的连线不改变它的值。它只是不那样工作。如果它被传递给服务,你可以忽略它。只读是指服务只返回它吗?@Bryan:是的。服务只返回它,我想准确地表达出来。你可以使用只读字段(而不是属性)并在类的构造中初始化它们。另外…,可能重复:这一点在今天更为重要,因为它已转向不可变类和C#-6.0对自动实现的get-only属性的支持。它实际上在反序列化过程中不调用默认构造函数。设置私有成员也没有问题。