繁体   English   中英

在WCF数据服务中使用枚举

[英]Using enums in WCF Data Services

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM