Getting Enum type from string of chars

702 views Asked by At

I've looked at similar questions but they don't seem to be dealing with the same issue I'm having.

I have an enum for CRUD permission testing defined as

public enum CRUDOperation
    {
        NotNeeded = 0,
        Read = 1,
        Create = 2,
        Update = 4,
        Delete = 8
    }

I didn't write this next part of code which is why I might be confused, but then the CRUD permission values associated with a role are put into a "Restrictions" string in the following manner.

            Restrictions = "";
            foreach (string inCrud in restrictions)
            {
                string crud = inCrud.ToUpper();
                int res = 0;
                if (crud.Contains('C'))
                    res |= (char)CRUDOperation.Create;
                if (crud.Contains('R'))
                    res |= (char)CRUDOperation.Read;
                if (crud.Contains('U'))
                    res |= (char)CRUDOperation.Update;
                if (crud.Contains('D'))
                    res |= (char)CRUDOperation.Delete;
                Restrictions += (char)res;
            }

And now I need to parse through this "Restrictions" string to check if a given role has the appropriate CRUDOperation permission levels. However the string is full of random ascii characters and I'm just having a hard time understanding how to do this correctly. I haven't worked with bitmasks really at all before. I'm trying to do this;

CRUDOperation operation = (CRUDOperation)Enum.Parse(typeof(CRUDOperation), p.Restrictions);

but i'm getting the error "Requested value ' ' was not found."

Does anyone have any advice?

2

There are 2 answers

0
Alioza On

Your problem in that code is that when you do this: Restrictions += (char)res; you are actually adding the character whose code is the result of your operation. The resulting Restrictions string can't be parsed as an enum.

I'm not sure why Restrictions is kept as a string. I would change the type of Restrictions to CRUDOperation and replace the first bit of code with this:

 Restrictions = CRUDOperation.None;
 foreach (string inCrud in restrictions)
 {
     string crud = inCrud.ToUpper();
     int res = 0;
     if (crud.Contains('C'))
        Restrictions |= CRUDOperation.Create;
     if (crud.Contains('R'))
        Restrictions |= CRUDOperation.Read;
     if (crud.Contains('U'))
        Restrictions |= CRUDOperation.Update;
     if (crud.Contains('D'))
        Restrictions |= CRUDOperation.Delete;
 }

This way you have the result directly.

If for some reason you have to have a string with the result you need to use a separator for the values you are adding: Restrictions += " " + (int)res; After that you can parse the string by splitting it and then parsing it (make sure to remove any empty entries before parsing).

2
Icemanind On

Before answering the question, I just want to point out that this is a crappy way of doing things. But I'm assuming you were inherited the code and you can't change it. But just keep in mind, code shouldn't work like this. The better way to do it is storing it in a List<CRUDOperation> instead of just concatenating it all to a string.

Okay now for your answer. Near as I can tell, what this code seems to be doing is building a string up of enum values. So if the code looked like this:

String Restrictions = "";
string[] restrictions = {"U", "C", "R"};

foreach (string inCrud in restrictions)
{
    string crud = inCrud.ToUpper();
    int res = 0;
    if (crud.Contains('C'))
        res |= (char)CRUDOperation.Create;
    if (crud.Contains('R'))
        res |= (char)CRUDOperation.Read;
    if (crud.Contains('U'))
        res |= (char)CRUDOperation.Update;
    if (crud.Contains('D'))
        res |= (char)CRUDOperation.Delete;
    Restrictions += (char)res;
}

This would build up a string of characters unreadable characters that contains this:

0x04, 0x02, 0x01

So if what you are needing to do is determine if someone has permissions based on this string, you can do something like this:

bool hasReadPermission = HasCrudPermission(Restrictions, CRUDOperation.Read);
bool hasCreatePermission = HasCrudPermission(Restrictions, CRUDOperation.Create);
bool hasUpdatePermission = HasCrudPermission(Restrictions, CRUDOperation.Update);
bool hasDeletePermission = HasCrudPermission(Restrictions, CRUDOperation.Delete);

    private bool HasCrudPermission(string restrictions, CRUDOperation permission)
    {
       return restrictions.Any(c => HasCrudPermission(c, permission));
    }

    private bool HasCrudPermission(char restriction, CRUDOperation permission)
    {
        return ((CRUDOperation)restriction) == permission;
    }