c# wcf enums wcf-data-services odata

c# - Uso de enumeraciones en WCF Data Services



enums wcf-data-services (6)

Estoy tratando de construir manualmente un servicio de datos WCF usando un modelo de datos POCO y no puedo descubrir cómo exponer correctamente los valores de enum . Asumiendo un modelo simple como:

public class Order { public int ID {get; set;} public string Description {get; set;} public OrderStatus Status {get; set;} } public enum OrderStatus { New, InProcess, Complete }

¿Cómo expone la valiosa información en la propiedad OrderStatus través del servicio de datos WCF de OData?

Si no hace nada, el servicio de datos genera un error de tiempo de ejecución (enumeración es una propiedad no válida). La única respuesta que he visto que al menos resuelve el error es marcar la propiedad enum como Ignorada, como por ejemplo:

[System.Data.Services.IgnoreProperties("Status")] public class Order ...

Esto funciona, pero lo obliga a "omitir" información valiosa de la capa de servicio. ¿Existen otras opciones para trabajar con valores de enumeración en WCF Data Services?

EDITAR: Tenga en cuenta que esto es WCF Data Services (también conocido como Astoria). No se trata de servicios WCF sin procesar, en cuyo caso las respuestas son más claras.


Como seguimiento, el enfoque de "envoltura" es, en última instancia, lo que funcionó. Esencialmente, se escribe una pequeña clase para envolver la enum y devolver los valores int primitivos en el Servicio de datos:

[IgnoreProperties("EnumValue")] public class OrderStatusWrapper { private OrderStatus _t; public int Value { get{ return (int)_t; } set { _t = (OrderStatus)value; } } public OrderStatus EnumValue { get { return _t; } set { _t = value; } } public static implicit operator OrderStatusWrapper(OrderStatus r) { return new OrderStatusWrapper { EnumValue = r }; } public static implicit operator OrderStatus(OrderStatusWrapper rw) { if (rw == null) return OrderStatus.Unresolved; else return rw.EnumValue; } }

Esto se basó en gran medida en los consejos dados para trabajar con los límites de enum de EF4:

http://blogs.msdn.com/b/alexj/archive/2009/06/05/tip-23-how-to-fake-enums-in-ef-4.aspx

Espero que esta técnica ayude a otros que siguen.


Las enumeraciones no son compatibles actualmente en los servicios de datos WCF (el protocolo OData tampoco los admite). La solución típica es utilizar valores constantes y de cadena, o valores enteros y constantes.


Necesitas escribir el propio QueryPrivider

public object GetPropertyValue(object target, ResourceProperty resourceProperty) { object result = null; PropertyInfo info = target.GetType().GetProperty(resourceProperty.Name); if (info != null) result = info.GetValue(target, null); if (result is Enum) return Convert.ToInt32(result); return result; } public ResourceType GetResourceType(object target) { ResourceType result = null; Type tp = target.GetType(); if (tp.IsEnum) { result = ResourceType.GetPrimitiveResourceType(typeof(Int32)); return result; } .... return result; }


Suponiendo la serialización de DataContract, así:

[DataContract] public class Order { [DataMember] public int ID {get; set;} [DataMember] public string Description {get; set;} [DataMember] public OrderStatus Status {get; set;} } [DataContract] public enum OrderStatus { [EnumMember] New, [EnumMember] InProcess, [EnumMember] Complete }


Tal vez podamos "engañarlo" con la siguiente solución:

[System.Data.Services.IgnoreProperties("Status")] public class Order { public int ID {get; set;} public string Description {get; set;} public OrderStatus Status {get; set;} public int StatusValue { get { return (int)this.Status; } set { // Add validation here this.Status = (OrderStatus)value; } } } public enum OrderStatus { New, InProcess, Complete }