Diin Diin - 2 months ago 20
C# Question

MVC 5 C# params array string

I am trying to create multiple roles for users. There is a common role for all which is Basic and an additional role of choice. I get the second role based on an integer value selected from a signup form. I then use a switch to match the value to the role name.
Below is what I tried but I get an error "Index was outside the bounds of the array".

string[] mt = new string[1];


switch (n)
{
case 1:
mt[0] = "Basic";
mt[1] = "Reader";
break;
case 2:
mt[0] = "Basic";
mt[1] = "Blogger";
break;
case 3:
mt[0] = "Basic";
mt[1] = "Editor";
break;
default:
mt[0] = "Basic";
break;
}


if (mt!= null)
{
result = await UserManager.AddToRolesAsync(user.Id, mt);
}


I don't really know if I am doing this the right way. Any help will be appreciated

Answer

Your array can only hold one value, because it has a length of 1. Increase its size to 2 using string[] mt = new string[2];

Then you can reduce some duplication, since you always assign "Basic" and then get rid of the redundant null check:

string[] mt = new string[2] {"Basic", null};
switch (n)
{
    case 1:
        mt[1] = "Reader";
        break;
    case 2:
        mt[1] = "Blogger";
        break;
    case 3:
        mt[1] = "Editor";
        break;
    default: break;
}

result = await UserManager.AddToRolesAsync(user.Id, mt);

HOWEVER: I would suggest a different clearer approach:

//create a dictionary with all roles
var roleDic = new Dictionary<int, string> {
     {1, "Reader"},
     {2, "Blogger"},
     {3, "Editor"},
};

//get the role that matches your n variable
var newRole = roleDic.FirstOrDefault (d => d.Key == n).Value;
//create the array for the UserManager
var roles = !String.IsNullOrEmpty(newRole) ? new [] {"Basic", newRole} : new[] {"Basic"};

result = await UserManager.AddToRolesAsync(user.Id, roles);

If you ever want to add more than one role per user and n becomes a collection of int values, this becomes:

var roleDic = new Dictionary<int, string> {
     {1, "Reader"},
     {2, "Blogger"},
     {3, "Editor"},
     {4, "SuperUser"},
     {5, "Administrator"},
     {6, "BackupAdmin"}
};

var rolestoAdd = new List<int> { 2, 4};

var newRoles = roleDic.Where(x => rolestoAdd.Contains(x.Key))
                     .Select (x => x.Value);
var roles = new List<string> {"Basic"};

roles.AddRange(newRoles);
result = await UserManager.AddToRolesAsync(user.Id, roles.ToArray());

This way you save yourself a clumsy switch statement which might grow over a couple of pages, once you hit some 20ish roles. Additionally you've seperated your role definition from your logic and (imho) it is more readable. (Others might find a gigantic switch or if-else block more concise, that is up to you.)

Comments