2011-11-16 11 views
7

que estoy usando el servicio WCFObtener el nombre de todos los DataMembers en un DataContract

Tengo un contrato de datos:

[DataContract] 
[KnownType(typeof(CustomBranches))] 
public class CustomBranches 
{ 
    [DataMember] 
    public int Id { get; set; } 

    [DataMember] 
    public string branch_name { get; set; } 

    [DataMember] 
    public string address_line_1 { get; set; } 

    [DataMember] 
    public string city_name { get; set; } 
} 

¿Es posible que yo pueda encontrar el nombre de todos los DataMembers en esta clase CustomBranches

Al igual que "ID", "nombre de la sucursal", etc

, gracias

Respuesta

4

En vista de que se trata de un contrato de datos que debe más probable es que todas estas propiedades disponibles, pero si no lo siguiente debe enumerar todas las propiedades de su tipo:

Type T =(typeof(T)); 
var properties = T.GetProperties(BindingFlags.Public|BindingFlags.Instance); 

reemplazar T con el tipo, y ya está bueno para ir. Dependiendo de sus necesidades, es posible que desee diferentes BindingFlags.

+1

Tipo Typ = (typeof (T)); T no puede ser tanto el tipo como el nombre de la variable Tipo. También T debe reservarse para tipos genéricos en genéricos. Gracias por el consejo de todos modos. – pasx

14

Lo que hay que hacer:

  • No es necesario añadir [KnownType(typeof(CustomBranches))] en su clase CustomBranches. Una clase siempre sabe sobre sí misma.
  • necesita filtrar las propiedades sólo para conseguir los que tienen el atributo [DataMember] (código nillls' devuelve todos ellos)
  • Las propiedades de miembro de datos también puede ser que no sea pública (que funciona si la serialización se está ejecutando en su totalidad la confianza)
  • Los miembros de los datos también pueden ser campos (no solo propiedades), por lo que debe tenerlos en cuenta también.

Este es un ejemplo de un código que hace todos ellos.

public class StackOverflow_8152252 
{ 
    public static void Test() 
    { 
     BindingFlags instancePublicAndNot = BindingFlags.Instance | 
      BindingFlags.Public | 
      BindingFlags.NonPublic; 
     var memberNames = typeof(CustomBranches) 
      .GetProperties(instancePublicAndNot) 
      .OfType<MemberInfo>() 
      .Union(typeof(CustomBranches).GetFields(instancePublicAndNot)) 
      .Where(x => Attribute.IsDefined(x, typeof(DataMemberAttribute))) 
      .Select(x => x.Name); 
     Console.WriteLine("All data member names"); 
     foreach (var memberName in memberNames) 
     { 
      Console.WriteLine(" {0}", memberName); 
     } 
    } 

    [DataContract] 
    public class CustomBranches 
    { 
     [DataMember] 
     public int Id { get; set; } 

     [DataMember] 
     public string branch_name { get; set; } 

     [DataMember] 
     public string address_line_1 { get; set; } 

     [DataMember] 
     public string city_name { get; set; } 

     public int NonDataMember { get; set; } 

     [DataMember] 
     public string FieldDataMember; 

     [DataMember] 
     internal string NonPublicMember { get; set; } 
    } 
} 
+0

Tenga en cuenta que los antepasados ​​de un tipo, si los hay, tienen su propio atributo 'DataContract'. Por lo tanto, para filtrar las propiedades y los campos, es posible que desee incluir el indicador de enlace 'DeclaredOnly'. En ese caso, también pase 'inherit: false' a' IsDefined'. – HappyNomad

3

he modificado respuesta de Carlos ligeramente hacer caso omiso de los miembros de datos decoradas con un atributo [NonSerialized]:

public class StackOverflow_8152252 
{ 
    public static void Test() 
    { 
     BindingFlags instancePublicAndNot = BindingFlags.Instance | 
      BindingFlags.Public | 
      BindingFlags.NonPublic; 
     var memberNames = typeof(CustomBranches) 
      .GetProperties(instancePublicAndNot) 
      .OfType<MemberInfo>() 
      .Union(typeof(CustomBranches).GetFields(instancePublicAndNot)) 
      .Where(x => Attribute.IsDefined(x, typeof(DataMemberAttribute)) 
        && !Attribute.IsDefined(x, typeof(NonSerializedAttribute))) 
      .Select(x => x.Name); 
     Console.WriteLine("All data member names"); 
     foreach (var memberName in memberNames) 
     { 
      Console.WriteLine(" {0}", memberName); 
     } 
    } 

    [DataContract] 
    public class CustomBranches 
    { 
     [DataMember] 
     public int Id { get; set; } 

     [DataMember] 
     [NonSerialized] 
     public string NonSerializedDataMember { get; set; } 
    } 
} 
Cuestiones relacionadas