How do I get a const string from Web.config?
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.
Explicat
Updated on June 05, 2022Comments
-
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 DELETEstatic readonly
instead, the compiler saysAn attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.
-
Explicat about 10 yearsI replaced const with static readonly, but this is giving me another error. See the edit in the original post.
-
Henk Mollema about 10 yearsOP is trying to use the constant as an attribute argument. You can't use
readonly
fields for that, so this won't work. -
Explicat about 10 yearsNice 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.