C# WCF 在没有“设置”的属性上窒息。任何解决方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2323277/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WCF chokes on properties with no "set ". Any workaround?
提问by Andrey
I have some class that I'm passing as a result of a service method, and that class has a get-only property:
我有一些作为服务方法的结果传递的类,并且该类具有 get-only 属性:
[DataContract]
public class ErrorBase
{
[DataMember]
public virtual string Message { get { return ""; } }
}
I'm getting an exception on service side:
我在服务端遇到异常:
System.Runtime.Serialization.InvalidDataContractException: No set method for property 'Message' in type 'MyNamespace.ErrorBase'.
System.Runtime.Serialization.InvalidDataContractException:“MyNamespace.ErrorBase”类型中的“Message”属性没有设置方法。
I have to have this property as only getter, I can't allow users to assign it a value. Any workaround I could use? Or am I missing some additional attribute?
我必须将此属性作为唯一的 getter,我不能允许用户为其分配值。我可以使用任何解决方法吗?或者我错过了一些额外的属性?
采纳答案by rh.
Give Message a public getter but protected setter, so that only subclasses (and the DataContractSerializer, because it cheats :) may modify the value.
给 Message 一个公共 getter 但受保护的 setter,这样只有子类(和 DataContractSerializer,因为它会作弊:)可以修改值。
回答by Russell
Even if you dont need to update the value, the setter is used by the WCFSerializer to deserialize the object (and re-set the value).
即使您不需要更新值,WCFSerializer 也会使用 setter 来反序列化对象(并重新设置值)。
This SO is what you are after: WCF DataContracts
这就是您所追求的: WCF DataContracts
回答by marc_s
Couldn't you just have a "do-nothing" setter??
你就不能有一个“什么都不做”的二传手吗??
[DataContract]
public class ErrorBase
{
[DataMember]
public virtual string Message
{
get { return ""; }
set { }
}
}
Or does the DataContract serializer barf at that, too??
或者 DataContract 序列化程序也会对此感到厌烦吗??
回答by Jojo Sardez
Properties with DataMember attribute always requires set. You should re write simmilar object on the client application since DataContract members can always be assigned values.
具有 DataMember 属性的属性始终需要设置。您应该在客户端应用程序上重新编写类似的对象,因为始终可以为 DataContract 成员分配值。
回答by Thomas Lundstr?m
I had this problem with ASP.NET MVC and me wanting to use DataContractSerializer in order to be able to control the names on the items in the JSON output. Eventually I switched serializer to JSON.NET, which supports properties without setters (which DataContractSerializer doesn't) and property name control (which the built-in JSON serializer in ASP.NET MVC doesn't) via [JsonProperty(PropertyName = "myName")]
.
我在 ASP.NET MVC 中遇到了这个问题,我想使用 DataContractSerializer 以便能够控制 JSON 输出中项目的名称。最终我将序列化器切换到 JSON.NET,它通过[JsonProperty(PropertyName = "myName")]
.
回答by Gilad
If it's a viable option, then instead of having ErrorBase
as the base class, define it as follows:
如果它是一个可行的选项,那么不要将其ErrorBase
作为基类,而是将其定义如下:
public interface IError
{
string Message
{
[OperationContract]
get;
// leave unattributed
set;
}
}
Now, even though a setter exists, it's inaccessible to the client via WCF channel, so it's as if it were private.
现在,即使存在 setter,客户端也无法通过 WCF 通道访问它,因此它就好像是私有的。
回答by Rikin Patel
[DataMember(Name = "PropertyName")]
public string PropertyName
{
get
{
return "";
}
private set
{ }
}
回答by Rob Lambert
If you only have a getter, why do you need to serialize the property at all. It seems like you could remove the DataMember attribute for the read-only property, and the serializer would just ignore the property.
如果你只有一个 getter,你为什么需要序列化这个属性。似乎您可以删除只读属性的 DataMember 属性,而序列化程序只会忽略该属性。
回答by Aaron Thomas
If your serializer is of type DataContractJsonSerializer
(or any DataContractSerializer
) you can also use DataContractSerializerSettings
in the constructor, with the SerializeReadOnlyTypes
property set to true.
如果您的序列化程序是类型DataContractJsonSerializer
(或任何类型DataContractSerializer
),您也可以DataContractSerializerSettings
在构造函数中使用,并将SerializeReadOnlyTypes
属性设置为 true。