Flags with web services

后端 未结 4 1204
灰色年华
灰色年华 2021-01-05 14:08

I have a flag attribute enumeration that is behind a web service as follows:

[Serializable,Flags]
public enum AccessLevels
{
    None = 0,
    Read = 1,
             


        
相关标签:
4条回答
  • 2021-01-05 14:20

    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.

    0 讨论(0)
  • 2021-01-05 14:24

    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.

    0 讨论(0)
  • 2021-01-05 14:27

    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
    }
    
    0 讨论(0)
  • 2021-01-05 14:28

    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.. )

    0 讨论(0)
提交回复
热议问题