在WCF数据服务中使用枚举

我正在尝试使用POCO数据模型手动构建WCF数据服务,我无法弄清楚如何正确公开enum值。 假设一个简单的模型,如:

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

如何通过OData WCF数据服务公开OrderStatus属性中的有价值信息?

如果不执行任何操作,则数据服务会生成运行时错误(枚举为无效属性)。 我见过的唯一解决错误的答案是将enum属性标记为已忽略,例如:

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

这有效,但它会强制您从服务层“省略”有价值的信息。 是否有其他选项可以在WCF数据服务中使用枚举值?

编辑:请注意这是WCF数据服务 (aka Astoria)。 这不是原始WCF服务,在这种情况下答案更清楚。

WCF数据服务当前不支持枚举(OData协议也不支持它们)。 典型的解决方法是使用字符串和常量值,或整数和常量值。

也许我们可以通过以下解决方法“欺骗”它:

 [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 } 

作为后续行动,“包装”方法最终起作用。 本质上,编写一个小类来包装enum并返回数据服务中的原始int值:

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

这很大程度上是基于为解决EF4的enum限制而提出的建议:

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

希望这项技术可以帮助其他人。

假设DataContract序列化,如下所示:

 [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 } 

您需要使枚举成为数据合同。

请看这里的例子: http : //consultingblogs.emc.com/merrickchaffer/archive/2007/04/03/Passing-Enum-values-into-WCF-Service-operations.aspx

[编辑]显然,这并不总是如下所示: 与WCF服务共享枚举

您需要编写自己的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; }