2009-07-13 5 views

Répondre

7

Les attributs de type connu sont transmis au constructeur DataContractSerializer. Vous pouvez customize the way this serializer is instantiated et fournir les types connus au constructor du sérialiseur en reflétant sur vos assemblys et en trouvant tous les types qui dérivent d'une classe de base.

Voici un exemple de code (non testé):

[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; 
    } 
} 
+0

je suis désolé, je suis assez mèche dans WCF, comment puis-je faire ce service toute une non par méthode? –

+0

En implémentant IServiceBehavior (http://msdn.microsoft.com/en-us/library/system.servicemodel.description.iservicebehavior.aspx) au lieu de IOperationBehavior –

+0

vous m'avez sauvé ... merci beaucoup. – user80855