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