如何从Web.config获取一个常量字符串?

3

在Entity Framework应用程序中进行授权时,我编写了这个类来检查当前用户是否属于指定的角色。

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;
        }

    }

现在,我可以仅允许特定角色的用户执行控制器操作。
[AuthorizeDesignatedRoles(DesignatedRoles = AuthorizeDesignatedRoles.DELETE)]
public HttpResponseMessage DeleteThisAndThat(long id) { ... }

问题在于我不想把指定的DELETE组名称放在代码中,而是放在web.config文件中。这样做后,Visual Studio会抱怨它不再是常量字符串。
如何使它再次成为常量字符串?
编辑:如果我省略了const关键字并将DELETE改为static readonly,编译器会说“属性参数必须是属性参数类型的常量表达式、typeof表达式或数组创建表达式。”

1
const是一个编译时常量。因此,如果它来自文件,则无法使用const。但问题在哪里?.NET会自动缓存配置文件 - Tim Schmelter
你在这里试图实现什么?AppSettings["GroupAuthorizedForDeleteAction"] 包含什么内容?关于static readonly字段的错误原因是,你只能在属性参数中使用常量,而readonly字段不是常量。 - Henk Mollema
只有特定的 Windows 角色才允许执行某些控制器操作。我希望不在代码中使用此特殊角色的名称,而是将其放在 web.config 文件中并使用密钥“GroupAuthorizedForDeleteAction”。 - Explicat
啊,我明白了。我在下面提出了一种可能的解决方案。 - Henk Mollema
2个回答

2

将AppSettings键存储在常量中,并在IsAuthorized方法中获取其值,这样如何:

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)
        {
            // ...
        }
    }
}

好主意!谢谢! 关于类型的一件事:您需要将角色显式地转换为数组,例如DesignatedRoles.Split(";").Select(..).ToArray()或使用IEnumerable<string> roles。 - Explicat

1
TL;DR: 使用 readonly 而不是 const
常量需要在编译时设置,并且在兼容更新中不会更改。编译器可以并且确实将常量的值从引用的程序集复制到其输出程序集中。
只读值可以在类型引用之前的代码中设置 (static readonly) 或在构造函数中设置 (成员 readonly),但随后不再强制进行更改。

1
我将const替换为static readonly,但是这给了我另一个错误。请参见原帖中的编辑。 - Explicat
2
OP 正试图将常量用作属性参数。你不能使用 readonly 字段来实现,所以这样做不起作用。 - Henk Mollema

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接