.net 具有只读属性的WCF DataContract
我试图从WCF中的服务方法返回复杂类型。我正在使用C#和.NET4。这个复杂类型是不变的(与.net字符串的方式相同)。此外,服务只返回它,从不将其作为参数接收 如果我试图只在属性上定义getter,就会出现运行时错误。我想这是因为没有setter会导致序列化失败。不过,我认为这种类型应该是不变的 例如:.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;} } 由于序列化问题
[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属性的支持。它实际上在反序列化过程中不调用默认构造函数。设置私有成员也没有问题。