Generally accepted way to avoid KnownType attribute for every derived class

前端 未结 6 1419
情书的邮戳
情书的邮戳 2020-12-14 17:19

Is there a generally accepted way to avoid having to use KnownType attributes on WCF services? I\'ve been doing some research, and it looks like there are two options:

6条回答
  •  被撕碎了的回忆
    2020-12-14 18:15

    I'd rather extract my custom types all at once and use it during serialization/deserialization. After reading this post, it took me a while to understand where to inject this list of types to be useful for serializer object. The answer was quite easy: this list is to be used as one of the input arguments of constructor of serializer object.

    1- I'm using two static generic methods for serialization and deserialization, this may be more or less the way others also do the job, or at least it is very clear for making comparison with your code:

        public static byte[] Serialize(T obj)
        {
            var serializer = new DataContractSerializer(typeof(T), MyGlobalObject.ResolveKnownTypes());
            var stream = new MemoryStream();
            using (var writer =
                XmlDictionaryWriter.CreateBinaryWriter(stream))
            {
                serializer.WriteObject(writer, obj);
            }
            return stream.ToArray();
        }
        public static T Deserialize(byte[] data)
        {
            var serializer = new DataContractSerializer(typeof(T), MyGlobalObject.ResolveKnownTypes());
            using (var stream = new MemoryStream(data))
            using (var reader =
                XmlDictionaryReader.CreateBinaryReader(
                    stream, XmlDictionaryReaderQuotas.Max))
            {
                return (T)serializer.ReadObject(reader);
            }
        }
    

    2- Please pay attention to constructor of DataContractSerializer. We have a second argument there, which is the entry point for injecting your known types to serializer object.

    3- I'm using a static method for extracting all of my own defined types from my own assemblies. your code for this static method may look like this:

        private static Type[] KnownTypes { get; set; }
        public static Type[] ResolveKnownTypes()
        {
            if (MyGlobalObject.KnownTypes == null)
            {
                List t = new List();
                List c = System.Reflection.Assembly.GetEntryAssembly().GetReferencedAssemblies().Where(b => b.Name == "DeveloperCode" | b.Name == "Library").ToList();
                foreach (AssemblyName n in c)
                {
                    System.Reflection.Assembly a = System.Reflection.Assembly.Load(n);
                    t.AddRange(a.GetTypes().ToList());
                }
                MyGlobalObject.KnownTypes = t.ToArray();
            }
            return IOChannel.KnownTypes;
        }
    

    Since I was not involved in WCF (I only needed a binary serialization for file operation), my solution may not exactly address the WCF architecture, but there must be access to constructor of serializer object from somewhere.

提交回复
热议问题