WCF DataContract with readonly properties
开发者_Python百科I'm trying to return a complex type from a service method in WCF. I'm using C# and .NET 4. This complex type is meant to be invariant (the same way .net strings are). Furthermore, the service only returns it and never receives it as an argument.
If I try to define only getters on properties I get a run time error. I guess this is because no setters causes serialization to fail. Still, I think this type should be invariant.
Example:
[DataContract]
class A
{
[DataMember]
int ReadOnlyProperty {get; private set;}
}
The service fails to load due to a problem with serialization.
Is there a way to make readonly properties on a WCF DataContract? Perhaps by replacing the serializer? If so, how? If not, what would you suggest for this problem?
Thanks,
Asafput [DataMember]
on backing field, you won't need a setter.
Make your setter public to satisfy the serializer, but just don't do anything on the setter. Not 'purist' but gets it done
public string MyProperty
{
get {
return this._myProperty
}
set {}
}
DataMember Field can't be readonly, because wcf dont serialize object as-is and every time befor deserialization starts creates new object instance, using default constructor. Dispatchers use setters to set field values after deserialization.
But all upper text can be a big mistake :)
To make them realy readonly, make the server logic, validating thiss field values.
You can't make the properties readonly, however you can get close to readonly by making the fields part of your contract instead of the properties:
[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;}
}
next make your internals accesable in wcf:
[assembly: InternalsVisibleTo("System.Runtime.Serialization")]
Some samples on how to use this to your advantage: wcf-and-datacontract-serialization-internals-and-tips
Like others have said, WCF needs getters and setters. That being said, I came here with the same question and the answers made me ask why I needed a read-only property. If you use the MVVM pattern, the class returned by the service is the Model and so should not be exposed directly by the UI. You can easily make the ViewModel read-only. Alternatively you could use a non UI-targetted facade class.
Actually, you can make the read-only fields serializable. You need to set the 'SerializeReadOnlyTypes' property of the DataContractSerializerSettings to 'True', when constructing the DataContractSerializer, as below:
var xmlSerializer = new DataContractSerializer(typeof(yourTypeHere), new DataContractSerializerSettings {SerializeReadOnlyTypes=true});
See the MSDN description and details, here: https://msdn.microsoft.com/en-us/library/system.runtime.serialization.datacontractserializersettings(v=vs.110).aspx
WCF needs to able to serialize / deserialize the property, which is not possible with a private property. To have a readonly property (within a complex type):
- Decorate class as [DataContract(IsReference = true)]
- Decorate each / the property as [DataMember]
- Public Get, Internal Set
[DataContract(IsReference = true)]
public class Format : ValueObject<Format>
{
[DataMember]
public int Height { get; internal set; }
}
Have you tried making the setter private?
Something like:
public string MyProperty
{
get;
private set;
}
精彩评论