我在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服务上正确提供标记?
编辑:
根据this文章,我可能无法做我想做的事情。 Ivan Krivyakov表示
枚举的透明度不足
事实证明,枚举并非如此 我们希望它们是透明的。 有三个棘手的问题:
- 如果服务器端代码声明枚举并分配特定数字 值为其成员,这些值 将不会被客户看到。
- 如果服务器端代码使用“复合”掩码声明[Flags]枚举 值(如白色=红色|绿色|蓝色), 它没有正确反映在 客户方。
- 如果服务器或客户端发送的“非法”值超出 枚举的范围,它导致了 XML反序列化器中的异常 另一边。
醇>
所以我想知道这是否只是一种限制而且是不可能的。
答案 0 :(得分:3)
我对此进行了大量研究,发现无法通过Web服务序列化枚举常量。请注意,要实现目标,您不需要枚举None或Full。这两个枚举可以用读/写组合暗示:
如果您的AccessLevels = Read |,您可以假设完全访问权限写 如果您的AccessLevels = 0 [无]
,则无您的枚举将如下所示:
[Serializable,Flags]
public enum AccessLevels
{
Read = 1,
Write = 2
}
答案 1 :(得分:0)
我遇到了类似的问题,并通过添加另一个Web服务来首先返回当前标志值。
然后那些成为我在比较中使用的值。
可能不是最干净的解决方案,但它有效。
编辑:
我的原始答案建议将值作为单独的Web服务传递,而不是在枚举中传递。
但是,看起来,在Web服务中映射到1,2,4的枚举0,1,2(即使设置了[Flags]属性)也是一个常见问题。
许多人建议的解决方案是修改原始枚举定义并从1而不是0开始。
答案 2 :(得分:0)
标志应为2的倍数,在您的情况下,标志为(0,1,2,3)。 尝试将结构的定义更改为:
[Serializable,Flags]
public enum AccessLevels{
None = 1,
Read = 2,
Write = 4,
Full = Read | Write}
看看它是否更好。
(我希望我不是自欺欺人,迟到了,我正在去床上的路上......)
答案 3 :(得分:0)
一种选择是提供更详细的类而不是枚举,例如
[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 -> None 0010 -> Read 0100 -> Write 0110 -> Full
所以要检查是否有任何权限,你应该看看该位是否已设置
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的定义,则客户端将默默地忽略该行为。