从其他程序集中添加KnownType的最简洁方法

时间:2013-08-01 13:05:30

标签: c# datacontractserializer datacontract

我在两个dinstinct程序集中有一个基类BaseClass和一个派生的DerivedClass。我使用以下方法(T = DerivedClass)序列化BaseClass的实例:

    public static string SerializeDataContract<T>(T obj)
    {
        using (var stream = new MemoryStream())
        {
            using (var reader = new StreamReader(stream))
            {
                var serializer = new DataContractSerializer(typeof(T));
                serializer.WriteObject(stream, obj);
                stream.Position = 0;
                return reader.ReadToEnd();
            }
        }
    }

我遇到以下异常:SerializationException:将任何静态未知的类型添加到已知类型列表中 - 例如,使用KnownTypeAttribute属性或将它们添加到传递给DataContractSerializer的已知类型列表中。

如何在不更改序列化方法的情况下序列化DerivedClass的实例? (记住:DerivedClass在另一个程序集中)

我目前使用以下内容,但我不是一个大粉丝。一些想法?

    //In base class
        [KnownType("GetKnownType")]
        public abstract class GetcReceiverContextBase
        {
            public static event Func<IEnumerable<Type>> KnownTypeRequired;

            private static IEnumerable<Type> GetKnownType()
            {
                var types = new List<Type>();
                if (KnownTypeRequired != null)
                    return KnownTypeRequired();

                return types.ToArray();
            }


//In derived Class
      public class DerivedClass : BaseClass
        {
            static MT514ContextMock()
            {
                KnownTypeRequired += () => new List<Type> { typeof(MT514ContextMock) };
            }

1 个答案:

答案 0 :(得分:0)

自:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/6b70e9f4-52bc-4fa9-a0ff-c0859e041e85/how-to-configure-serviceknowntype-in-appconfig

以下是帖子的引用(如果链接死亡),但在上面的链接中有一些额外的讨论。

只需使用[ServiceKnownType(“GetKnownTypes”,typeof(Helper))]属性,然后让GetKnownTypes方法从文件中读取AssemblyQualifiedNames并返回类型。

[ServiceKnownType("GetKnownTypes", typeof(Helper))]
public interface MyService
{
    ...
}

static class Helper
{
    public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider)
    {
        List<Type> knownTypes = new List<System.Type>();
        // Add any types to include here.           
        string[] types = File.ReadAllLines(@"..\..\..\types.txt");
        foreach (string type in types)
        {
            knownTypes.Add(Type.GetType(type));
        }

        return knownTypes;
    }
}

types.txt:  NameSpace.MyType,MyAssembly,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null  NameSpace.MyOtherType,MyAssembly,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null

你也可以看一下:

How do you configure WCF known types programmatically?