问题
I have various classes which I want to expose as Complex Types in WCF, so I add [DataContract] and [DataMember] attributes as necessary on those types and properties.
However if I want to have them inherit from an abstract base class (for example Person inherits from abstract EntityBase), I get an error that the type "cannot inherit from a type that is not marked with DataContractAttribute or SerializableAttribute".
The problem is, if I add [DataContract] attribute to the base class, then that base class is exposed to the client via the WSDL. Not a huge deal I guess, but I would prefer my client doesn't know about my internal implementation.
If I add the [Serializable] attribute to the base class, then it seemed to work at first (it could be serialized but EntityBase was not referenced in the WSDL), but now if I add any properties to EntityBase then it will also complain that its properties are not serializable. (For example I add an ICollection then I get an error that RuleViolation is not serializable).
Unfortunately there seems to be no analogue to [IgnoreDataMember] for a [Serializable] type ([NonSerialized applies only to fields, not properties).
So basically I want to declare this base type but don't need any of its members to be serialized; is there any way to set this up in WCF so the client doesn't see this base type?
回答1:
Did you try not marking your entities with [DataContract]
and [DataMember]
at all (so that default serialization is used) and instead marking base class properties with [IgnoreDataMember]
?
You always have several choices and I'm afraid you will not like any of them.
- Create a set of DTO objects and convert entities to DTO. This is generally a best practice if you want to hide your inner implementation.
- Create a surrogate class (implement IDataContractSuroggate) for each entity so that you have control over serialization - I'm not sure if this avoids the problem.
- Upgrade to .NET 4.0 and use EF with POCO classes (with no EntityBase as parent)
Best regards, Ladislav
回答2:
I think you have to use the KnownType attribute. For instance see WCF issues with KnownType for Dictionary
[EDIT] A more complete discussion of this problem and its solution can be found here: WCF: Interfaces, Generics and ServiceKnownType
来源:https://stackoverflow.com/questions/3496952/inherit-from-abstract-class-in-wcf-without-exposing-that-class