代码之家  ›  专栏  ›  技术社区  ›  Chen Kinnrot

WCF服务已知类型属性问题

wcf
  •  3
  • Chen Kinnrot  · 技术社区  · 15 年前

    我想添加一个服务行为(或者您建议的任何行为),它将自动将类型从dll插入到服务的已知类型

    有可能吗?怎样?

    1 回复  |  直到 15 年前
        1
  •  7
  •   Darin Dimitrov    15 年前

    将已知类型属性传递给DataContractSerializer构造函数。你可以 customize the way this serializer is instantiated 并将已知类型提供给 constructor 通过对程序集进行反射并查找从基类派生的所有类型来实现序列化。

    以下是示例代码(未测试):

    [ServiceContract]
    public interface FooContract
    {
        [OperationContract]
        [KnownTypesDataContractFormat(typeof(SomeBaseType))]
        void MyOperation(SomeBaseType arg);
    }
    
    public class KnownTypesDataContractFormatAttribute : Attribute, IOperationBehavior
    {
        public Type BaseType { get; private set; }
        public KnownTypesDataContractFormatAttribute(Type baseType)
        {
            BaseType = baseType;
        }
    
        public void AddBindingParameters(OperationDescription description, BindingParameterCollection parameters)
        { }
    
        public void ApplyClientBehavior(OperationDescription description, System.ServiceModel.Dispatcher.ClientOperation proxy)
        {
            IOperationBehavior innerBehavior = new KnownTypesDataContractSerializerOperationBehavior(description, BaseType);
            innerBehavior.ApplyClientBehavior(description, proxy);
        }
    
    
        public void ApplyDispatchBehavior(OperationDescription description, System.ServiceModel.Dispatcher.DispatchOperation dispatch)
        {
            IOperationBehavior innerBehavior = new KnownTypesDataContractSerializerOperationBehavior(description, BaseType);
            innerBehavior.ApplyDispatchBehavior(description, dispatch);
        }
    
        public void Validate(OperationDescription description)
        { }
    }
    
    public class KnownTypesDataContractSerializerOperationBehavior : DataContractSerializerOperationBehavior
    {
        public Type BaseType { get; private set; }
        public KnownTypesDataContractSerializerOperationBehavior(OperationDescription operationDescription, Type baseType) : base(operationDescription) 
        {
            BaseType = baseType;
        }
    
        public override XmlObjectSerializer CreateSerializer(Type type, string name, string ns, IList<Type> knownTypes)
        {
            return new DataContractSerializer(type, name, ns, knownTypes);
        }
    
        public override XmlObjectSerializer CreateSerializer(Type type, XmlDictionaryString name, XmlDictionaryString ns, IList<Type> knownTypes)
        {
            return new DataContractSerializer(type, name, ns, knownTypes);
        }
    
        private IEnumerable<Type> GetKnownTypes()
        {
            // Try to find all types that derive from BaseType in the 
            // executing assembly and add them to the knownTypes collection
            return 
                from type in Assembly.GetExecutingAssembly().GetTypes()
                where type != BaseType && BaseType.IsAssignableFrom(type)
                select type;
        }
    }