How do I get a const string from Web.config?

11,060

Solution 1

What about storing the AppSettings key in the constant and fetch its value in the IsAuthorized method:

public class AuthorizeDesignatedRoles : AuthorizeAttribute
{
    public const string DELETE = "GroupAuthorizedForDeleteAction";

    public string DesignatedRoles { get; set; }

    protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext) {
    {
        // ...

        string[] roles = DesignatedRoles.Split(';')
                                        .Select(s => ConfigurationManager.AppSettings[s].ToString())
                                        .ToArray();

        foreach (string role in roles)
        {
            // ...
        }
    }
}

Solution 2

TL;DR: Use readonly rather than const.

Constants need to be set at compile time, and not change in compatible updates. The compiler can and does copy the values of constants from referenced assemblies into their output assembly.

Read-only values can be set in code before references to the type (static readonly) or in the constructor (member readonly) but no further changes is then enforced.

Share:
11,060
Explicat
Author by

Explicat

Updated on June 05, 2022

Comments

  • Explicat
    Explicat almost 2 years

    For authorization in an Entity Framework application, I've written this class which check's whether the current user is in the specified role.

    public class AuthorizeDesignatedRoles : AuthorizeAttribute {
    
            public const string DELETE = System.Configuration.ConfigurationManager.AppSettings["GroupAuthorizedForDeleteAction"].ToString();
            public string DesignatedRoles { get; set; }
    
            protected override bool IsAuthorized(System.Web.Http.Controllers.HttpActionContext actionContext) {
                bool isAuthorizedBase = base.IsAuthorized(actionContext);
                if (!isAuthorizedBase)
                    return false;
    
    
                string[] roles = DesignatedRoles.Split(';');  // Multiple roles can be seperated by a semicolon ;
                foreach (string role in roles) {
                    if (System.Web.Security.Roles.IsUserInRole(role))
                        return true;
                }
                return false;
            }
    
        }
    

    Now I can allow controller actions only to be carried out by users who are in a designated role.

    [AuthorizeDesignatedRoles(DesignatedRoles = AuthorizeDesignatedRoles.DELETE)]
    public HttpResponseMessage DeleteThisAndThat(long id) { ... }
    

    The problem is that I do not want to put the name of the designated DELETE group in the code but in the web.config file. By doing so, Visual Studio complains that it is not a constant string any more.

    How can I make it a constant string again?

    Edit: When I leave out the const keyword and make DELETE static readonly instead, the compiler says An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.

  • Explicat
    Explicat about 10 years
    I replaced const with static readonly, but this is giving me another error. See the edit in the original post.
  • Henk Mollema
    Henk Mollema about 10 years
    OP is trying to use the constant as an attribute argument. You can't use readonly fields for that, so this won't work.
  • Explicat
    Explicat about 10 years
    Nice idea! Thank you! One thing with the types: You need to cast the roles explicitly to an array, like DesignatedRoles.Split(";").Select(..).ToArray() or use IEnumerable<string> roles.