【问题标题】:Passing enum value as parameter将枚举值作为参数传递
【发布时间】:2016-02-05 11:10:06
【问题描述】:

我无法从 WCF 客户端传递多个 enum 值。

class Client
{
    static void Main(string[] args)
    {
        ChannelFactory<IWCFService> channelFactor = new ChannelFactory<IWCFService>("HellowWorldServiceEndpoint");
        channelFactor.Open();

        IWCFService proxy = channelFactor.CreateChannel();
        Console.WriteLine(proxy.GetEnumString(EnumComponents.enumVal1)); // -> SUCCEDED HERE (only one Enum value)
        // Console.WriteLine(proxy.GetEnumString(EnumComponents.enumVal1| EnumComponents.enumVal2)); // -> **** FAILS HERE with invalid enum type. *****
        Console.Read();
    }
}

例外是, 尝试序列化参数http://tempuri.org/:components 时出错。 InnerException 消息是“枚举值 'enumVal1, enumVal2”对于类型“Microsoft.Geospatial.Data.Gateway.ObjectModel.EnumComponents”无效并且无法序列化。如果类型具有 DataContractAttribute 属性,请确保存在必要的枚举值并使用 EnumMemberAttribute 属性进行标记。'。请参阅 InnerException 了解更多详情

仅供参考,枚举来自一个公共库,该库作为参考添加到 WCFclient、WCFserver 和 WCFinterface 中。

如果是正常的函数调用,同样的炒锅。有没有办法解决这个问题?

【问题讨论】:

标签: c# .net wcf enums


【解决方案1】:

您发送一堆|-ed enum 值的唯一原因是enum 象征着标志。

WCF supports 在少数情况下使用enumsDataContract - 其中之一是标志枚举

如果您的enumFlagsAttribute 修饰它,则序列化按以下方式完成:

  • 尝试查找映射到数值的枚举成员(应用了EnumMemberAttribute 属性)。如果找到,请发送仅包含该成员的列表。
  • 尝试将数值分解为总和,以便有枚举成员(每个都应用EnumMemberAttribute 属性)映射到总和的每个部分。发送所有这些成员的列表。请注意,贪心算法用于找到这样的总和,因此即使存在这样的总和也不能保证找到。为避免此问题,请确保枚举成员的数值是 2 的幂。
  • 如果前两个步骤失败,并且数值非零,则抛出 SerializationException。如果数值为零,则发送空列表。

因此,您需要您的枚举如下所示:

[DataContract]
[Flags]
enum EnumComponents
{
    [EnumMember]
    enumVal1,

    [EnumMember]
    enumVal2
}

如果enum 来自外部来源并且它没有FlagsAttribute,则您必须自己将数值分解为用EnumMemberAttribute 装饰的枚举成员的总和。

【讨论】:

  • 在我的情况下,枚举来自外部来源,您能否详细说明(如果可能提供一些代码 sn-p)如何做到这一点。仅供参考,枚举值是 2 的幂。并且枚举有 [Flags].. 枚举看起来像这样,[Flags] public enum EnumComponents { enumVal1 = 1, enumVal2 = 2, enumVal3 = 4, enumVal4 = 8, }
  • 您的enum 似乎没有EnumMemberAttribute,因此WCF 提供的算法无法将enumVal1 | enumVal2 分解为发送它们所需的2 个分隔值。
  • 直接为枚举传递值是否有效?如果您的枚举来自外部源,那么您可以编写自己的类,该类具有赋予您的枚举值的逻辑,然后使用它
  • 一种解决方案可能是将GetEnumString 的签名更改为接收int 并使用转换为intenumVal1 | enumVal2 的值调用它,然后,在方法本身中,您将不得不将其转换回来。另一个可能是使用您自己的enum 并在调用代理方法之前和之后来回翻译。
猜你喜欢
  • 2012-04-18
  • 1970-01-01
  • 1970-01-01
  • 2011-04-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多