17

我正在尝试使用 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
}

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

如果您什么都不做,数据服务会生成运行时错误(枚举是无效属性)。我看到的至少解决错误的唯一答案是将enum属性标记为已忽略,例如:

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

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

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

4

6 回答 6

16

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

于 2010-08-26T00:59:54.767 回答
5

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

[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
}
于 2010-08-26T14:07:25.717 回答
5

作为后续,“包装器”方法最终是有效的。本质上,编写了一个小类来包装数据服务中的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

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

于 2010-08-27T21:55:57.057 回答
2

假设 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
}
于 2010-08-25T21:18:40.510 回答
0

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

有关示例,请参见此处:http: //consultingblogs.emc.com/merrickchaffer/archive/2007/04/03/Passing-Enum-values-into-WCF-Service-operations.aspx

[编辑] 显然,情况并非总是如此: Sharing Enum with WCF Service

于 2010-08-25T21:16:41.213 回答
0

您需要编写自己的 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;
    }
于 2011-12-09T09:26:33.880 回答