views:

272

answers:

3

Hi,

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 recieves 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,
Asaf

+2  A: 

Have you tried making the setter private?

Something like:

public string MyProperty
{
get;
private set;
}
Bryan Denny
Yep. That's exactly my problem.
Asaf R
So this fixed it? Or this is what you were trying?
Bryan Denny
@Bryan: It doesn't work. If I make MyProperty a [DataMember] I get a runtime error caused, to my best understanding, from the serialization. It happens as soon as the service loads - not even during a client operation.
Asaf R
@AsafR: Correct, it seems that you must have a get/set for all fields for the serialization/deserialization to work. I don't think there is a way around this from everything I've read :(
Bryan Denny
@Bryan: If you want to put your conclusion in your above answer, I'll be happy to make it the accepted answer.
Asaf R
+3  A: 

put [DataMember] on backing field, you won't need a setter.

Krzysztof Koźmic
But it won't be readonly, and won't express that it should be readonly.
Asaf R
it will never be readonly. Datacontract when transferred over the wire is just an XML. you can't make piece of XML readonly. You can't **make** whoever is on the other end of the wire not to change its value. It just does not work like that.
Krzysztof Koźmic
You could simply ignore the value if it is passed to the service? By read only do you mean that the service only returns it?
Bryan Denny
@Bryan: yep. The service only returns it and I want to express exactly that.
Asaf R
A: 

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.

Stremlenye