I have a flag attribute enumeration that is behind a web service as follows:
[Serializable,Flags]
public enum AccessLevels
{
None = 0,
Read = 1,
I had a similar problem and got round it by adding another web service to return the currect flag values first.
Those then became the values I used in the compare.
Might not be the cleanest solution but it works.
Edit:
My original answer suggested that the values are passed across as a separate web service rather than within an enum.
However, poking around, it appears that an enumeration of 0,1,2 being mapped to 1,2,4 across a web service (even that the [Flags] attribute is set) is a common problem.
The solution suggested by a number of people is to modify the original enumeration definition and start from 1 rather than 0.
One option would be to provide a more verbose class instead of the enum e.g.
[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;
}
}
}
The other option I can see is providing a method in what ever language they are using to successfully interoperate the integer you are sending. The flag operator means that c# does bit masking to find if a individual flag is marked
0001 -> None 0010 -> Read 0100 -> Write 0110 -> Full
so to check for any permission you should see if that bit is set
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.
}
Please note this second solution is more fragile, if you change the definition of accessLevels you client will silently miss behave.
I have done extensive research on this and found that it is not possible to serialize enumeration constants through a web service. Note that to accomplish your goal you don't need the enumerations None or Full. These two enumerations can be implied with read / write combination:
You could assume full access if your AccessLevels = Read | Write and none if your AccessLevels = 0 [nothing]
Your enumerations would look like this:
[Serializable,Flags]
public enum AccessLevels
{
Read = 1,
Write = 2
}
Flags should be multiples of two, and in your case your flags are (0,1,2,3). Try change your definition of the struct to:
[Serializable,Flags]
public enum AccessLevels{
None = 1,
Read = 2,
Write = 4,
Full = Read | Write}
And see if it works better.
(I hope Im not making a fool of myself, its late and Im on my way to the bed.. )