.NET Framework Bookmark and Share   
 index > Windows Communication Foundation > Add KnownType from code?
 

Add KnownType from code?

http://blogs.msdn.com/sowmy/archive/2006/06/06/618877.aspxmentions "3.Known types can also be passed to the constructor of the DataContractSerializer" which sounds like a splendid idea.

However, WCF creates the DataContractSerializer for me, right? I get little say in the matter AFAICT.

What am I missing? (I have used the config file approach for now, but I naturally want to eliminate this kludge from there!) I use CultureInfo in quite many classes, so I want to avoid the KnownType attribute too.
SAAB9-3
Not really, if you use the attribute option (in that thread, search for NetDataContractAttribute). This way all you'll need to do is to apply that attribute to each [ServiceContract] interface.
Carlos Figueira

I believe that the post is talking about the following overload for DataContractSerializer;

public
DataContractSerializer(Type type, string rootName, string rootNamespace, IEnumerable<Type> knownTypes);

It is true that DCSerializer is created by the WCF stack and a way to plugin your KTs is through the [ServiceKnownTypeAttribute] (on Services/operations) or [KnownTypeAttribute] (in DataContracts)

If you are doing your own serialization by instantiating DCSerializer, then you can use the ctor overload to pass your KTs


Amit Sharma
Amit Sharma R

It is true that DCSerializer is created by the WCF stack and a way to plugin your KTs is through the [ServiceKnownTypeAttribute] (on Services/operations) or [KnownTypeAttribute] (in DataContracts)


OK, but are these the only ways?

I have several interfaces exposing CultureInfo as a parameter. Adding these attributes is not convenient.

Don't get me wrong, I enjoy using attributes, but for this purpose I see no benefits and many drawbacks. (and don't get me started on the rampant abuse of .config files...)
SAAB9-3
>>I have several interfaces exposing CultureInfo as a parameter. Adding these attributes is not convenient.
can you please clarify theinconvenience here?


Amit Sharma
Amit Sharma R
WCF creates the serializer for you, but you can change the DataContractSerializerOperationBehavior to change how it's created. See the post at thread http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/59166949-0082-4ecf-954a-5ff5cc04634e for an example on how this can be done (in that post we change the DataContractSerializer (DCS)for the NetDataContractSerializer, but it can be used to simply change the parameters of the DCS as well.

Another option to declare known types in code (and not in config) would be to use the overload of [KnownType] (or [ServiceKnownType]) which takes a name of the method that will actually return the known types. This way you can effectively return all the known types while using only 1 attribute for each service (or base type, whichever you prefer).

        [DataContract]
        public class MyDerived1 : MyBase { }
        [DataContract]
        public class MyDerived2 : MyBase { }
        [DataContract]
        public class MyDerived3 : MyBase { }
        [KnownType("GetKnownTypes")]
        [DataContract]
        public class MyBase
        {
            public static Type[] GetKnownTypes()
            {
                return new Type[] { typeof(MyDerived1), typeof(MyDerived2), typeof(MyDerived3) };
            }
        }

        [DataContract]
        public class My2Derived1 : MyBase2 { }
        [DataContract]
        public class My2Derived2 : MyBase2 { }
        [DataContract]
        public class My2Derived3 : MyBase2 { }
        [DataContract]
        public class MyBase2 { }
        [ServiceContract]
        [ServiceKnownType("GetKnownTypes", typeof(KnownTypesForITest))]
        public interface ITest
        {
            [OperationContract]
            MyBase2 Echo(MyBase2 input);
        }
        public class KnownTypesForITest
        {
            public static Type[] GetKnownTypes()
            {
                return new Type[] { typeof(My2Derived1), typeof(My2Derived2), typeof(My2Derived3) };
            }
        }

Carlos Figueira
>>I have several interfaces exposing CultureInfo as a parameter. Adding these attributes is not convenient.
can you please clarify theinconvenience here?


Amit Sharma

I have an application with 40+ interfaces, a dozen of which has a total of about 20+ methods that carries a CultureInfo parameter.

Even if I bite the bullet and grease these methods accordingly, there is still the question of having to tell my team to do this properly in the future. I am looking for a solution that would solve both my concerns in one fell sweep.

Messing with the config file works. But I do not approve of bloating the config file for no good reason.

However: It is easy to enumerate all parameters of all methods of all my interfaces at runtime. I already do some pre-processing in this area to help cover some of WCF's shortfalls.

So if there was a way for me to add a custom attribute at runtime, I would be home and dry.

Any suggestions?
SAAB9-3
WCF creates the serializer for you, but you can change the DataContractSerializerOperationBehavior to change how it's created. See the post at thread http://social.msdn.microsoft.com/Forums/en-US/wcf/thread/59166949-0082-4ecf-954a-5ff5cc04634e for an example on how this can be done (in that post we change the DataContractSerializer (DCS)for the NetDataContractSerializer, but it can be used to simply change the parameters of the DCS as well.
Unless I am missing something, this requires me to implement IContractBehavior in each and every class implementing a server interface.

I have 40+ interfaces (and counting) in my WCF application.
SAAB9-3
There is a constructor of ServiceKnownType that takes a method in which you can return a collection of Type objects for the known types
Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
Twitter: richardblewett
Richard Blewett
Not really, if you use the attribute option (in that thread, search for NetDataContractAttribute). This way all you'll need to do is to apply that attribute to each [ServiceContract] interface.
Carlos Figueira

You can use google to search for other answers

Custom Search

More Threads

• Dicionatry<string, object> Types must use StringComparer.OrdinalIgnoreCase on client side
• WCF Service not usable from a client DLL
• running WCF on 2 machines
• WCF tries to request every 10 seconds itsself - Timeout BUG
• Debug a WCF
• WCF Architecture
• Windows Service Timeout
• Invisible messages in MSMQ
• Getting runtime error with 2.0 proxy when same response object is used for two interfaces
• WCF binding recommendations