I\'m trying to manually build a WCF Data Service using a POCO data model and I cannot figure out how to properly expose enum
values. Assuming a simple model lik
Enums are currently not supported in WCF Data Services (the OData protocol doesn't support them either). The typical workaround is to use string and constant values, or integer and constant values.
You need to make the enum a Data Contract.
See here for an example: http://consultingblogs.emc.com/merrickchaffer/archive/2007/04/03/Passing-Enum-values-into-WCF-Service-operations.aspx
[Edit] Apparently, that's not always the case as seen here: Sharing Enum with WCF Service
You need to write own 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;
}
Assuming DataContract Serialization, like so:
[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
}
As follow-up, the "wrapper" approach is ultimately what worked. Essentially, a small class is written to wrap the enum
and return primitive int
values in the Data Service:
[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;
}
}
This was largely based on the advice given for working around EF4's enum
limits:
http://blogs.msdn.com/b/alexj/archive/2009/06/05/tip-23-how-to-fake-enums-in-ef-4.aspx
Hope this technique helps others that follow.
Maybe we can "cheat" it with the below workaround:
[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
}