Figure out if an instance of Object is DataContract serializable in WCF
I was reading the reference page on what types are serializable by WCF and it is ambiguous on what types are automatically KnownType and does that are not. Can anyone shed some light on that? For example, if my DataContract has a member of type Object, it will serialize fine if I pass a string, but not if I pass a Dictionary. The dictionary would need a KnownType, despite being mentioned as supported in that page. With that I have two questions:
So the question is, what are the automatic KnowTypes that WCF always use?
I need code that will figure out if an instance of object is KnownType by default. One solution would be to come up with an exhaustive list from the answer to 1 and than check the object against each one with a "obj is type" statement but that seems a bad implementation. Is there a smarter way?
EDIT:
This reference lists the the types that are known by default. All primitives less DateTimeOffset plus XmlElement. So only two remains: How can I known if an Object is of primitive ty开发者_JS百科pe?
EDIT 2: typeof(obj).IsPrimitive will do most of the work!
A known type is needed when only the base type is visible in the operation contract signature but some derived type could be returned. Example:
[OperationContract]
BaseClass Foo();
and in the implementation:
public Foo()
{
return DerivedClass();
}
where DerivedClass
derives from BaseClass
. So you need to specify this explicitly either at the BaseClass
declaration:
[KnownType(typeof(DerivedClass))]
[DataContract]
public class BaseClass { }
or using the [ServiceKnownType]
at the service contract declaration:
[ServiceContract]
[ServiceKnownType(typeof(DerivedClass))]
public interface IService
{
[OperationContract]
BaseClass Foo();
}
or using the config file:
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type="SomeNs.BaseClass, SomeAssembly">
<knownType type="SomeNs.DerivedClass, SomeAssembly"/>
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
UPDATE:
As the documentation states it you don't need this for primitive types:
The following types built into the .NET Framework can all be serialized and are considered to be primitive types: Byte, SByte, Int16, Int32, Int64, UInt16, UInt32, UInt64, Single, Double, Boolean, Char, Decimal, Object, and String.
精彩评论