标志与Web服务

我有一个标志属性枚举,它位于Web服务后面,如下所示:

[Serializable,Flags] public enum AccessLevels { None = 0, Read = 1, Write = 2, Full = Read | Write } 

我的问题是我的网络服务的消费者没有枚举的原始常量值。 生成的代理类客户端端具有以下内容:

 { None = 1, Read = 2, Write = 4, Full = 8 } 

因此,当消费者检查“读取”访问时,即使“testItem”为“Full”,这也将是假的。

 ((testItem & Svc.Read) == Svc.Read) 

如何通过Web服务正确提供标志?

编辑:

根据这篇文章,我可能无法做我想做的事情。 Ivan Krivyakov说

Enum的透明度不完美

事实certificate,枚举并不像我们希望的那样透明。 有三个棘手的问题:

  1. 如果服务器端代码声明枚举并为其成员分配特定的数值,则客户端将无法看到这些值。
  2. 如果服务器端代码声明带有“复合”掩码值的[Flags]枚举(如白色=红色|绿色|蓝色),则它在客户端没有正确反映。
  3. 如果服务器或客户端发送超出枚举范围的“非法”值,则会在另一侧的XML反序列化器中导致exception。

所以我想知道这只是一个限制,是不可能的。

我对此进行了大量研究,发现无法通过Web服务序列化枚举常量。 请注意,要实现目标,您不需要枚举None或Full。 这两个枚举可以用读/写组合暗示:

如果您的AccessLevels = Read |,您可以假设完全访问权限 如果您的AccessLevels = 0 [无]则写入和无

您的枚举将如下所示:

 [Serializable,Flags] public enum AccessLevels { Read = 1, Write = 2 } 

标志应该是2的倍数,在你的情况下你的标志是(0,1,2,3)。 尝试将结构的定义更改为:

 [Serializable,Flags] public enum AccessLevels{ None = 1, Read = 2, Write = 4, Full = Read | Write} 

看看它是否更好。

(我希望我不是自欺欺人,迟到了,我正在去床上的路上……)

一种选择是提供更冗长的类而不是枚举例如

 [Serializable] public class AccessPermission{ public boolean None{get;set;} public boolean Read{get;set;} public boolean Write{get;set;} public boolean Full{get;set;} public AccessPermission(AccessLevels level){ None = false; Read = false; Write = false; Full = false; switch(level){ case AccessLevels.None: break; case AccessLevels.Read: Read = true; break; case AccessLevels.Write: Write = true; break; case AccessLevels.Full: Read = true; Write = true; Full = true; break; } } } 

我能看到的另一个选项是提供一种方法,用它们用什么语言来成功地互操作你发送的整数。 标志运算符意味着c#进行位屏蔽以查找是否标记了单个标志

 0001  - >无
 0010  - >阅读
 0100  - >写
 0110  - >完整

所以要检查是否有任何权限,你应该看看是否设置了该位

 public static boolean CanRead(int accessLevel){ return (accessLevel | 2) > 0 // return true if read bit set, using bitwise or } public static boolean CanWrite(int accessLevel){ return (accessLevel | 4) > 0 // return true of write bit set. } 

请注意,第二个解决方案更加脆弱,如果您更改了accessLevels的定义,则客户端将默默地忽略该行为。

我遇到了类似的问题,并通过添加另一个Web服务来首先返回当前标志值。

然后那些成为我在比较中使用的值。

可能不是最干净的解决方案,但它的工作原理。

编辑:

我的原始答案表明,这些值作为单独的Web服务传递,而不是在枚举中传递。

但是,看起来,在Web服务中映射到1,2,4的枚举0,1,2(即使设置了[Flags]属性)也是常见的问题。

许多人建议的解决方案是修改原始枚举定义并从1而不是0开始。