如何使用键(数组键访问)检索ConfigurationCollection中的ConfigurationElement?

5
我需要在我的自定义配置部分中执行类似以下内容的操作:
ConfigurationManager.ConnectionStrings["mongodb"]

上面的字符串“mongodb”是我用来访问类型为System.Configuration.ConnectionStringSettings的元素的关键字。我希望对我的自定义集合执行相同的操作:

[ConfigurationCollection(typeof(Question))]
public class QuestionCollection : ConfigurationElementCollection
{   

    public override bool IsReadOnly()
    {
        return false;
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new Question();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((Question)element).id;
    }

    //Is here?
    public Question this[int idx]
    {
        get {
            return (Question)BaseGet(idx);
        }

        set
        {
            if (BaseGet(idx) != null)
                BaseRemoveAt(idx);

            BaseAdd(idx, value);
        }
    }

}

我想知道上面所注释的方法是否是我想要的方式...但是我不知道如何执行它...我想要用来访问的键的类型是整数。
假设我有以下配置:
    <securityQuestions>
    <questions>
      <add id="3" value="What is your name?" default="true"/>
      <add id="4" value="What is your age?"/>
    </questions>
</securityQuestions>

如何使用Section.Questions[3](3不是位置,而是键)访问第一个元素(id = 3)?

4个回答

4
感谢Aleksei Chepovoi的建议。解决方案如下:
[ConfigurationCollection(typeof(Question))]
public class QuestionCollection : ConfigurationElementCollection
{   

    public override bool IsReadOnly()
    {
        return false;
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new Question();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((Question)element).id;
    }

    public Question this[int id]
    {
        get
        {
           return this.OfType<Question>().FirstOrDefault(item => item.id == id);
        }
    }

}

索引器的签名应该是:public new Question this[int id]吗? - Brian Colavito

3
您可以强制使用键检索configurationElement项以触发此重载:
public Question GetQuestion(int id)
{
    get
    {
       return (Question)this.BaseGet((object)id);
    }
}

1
我假设您的自定义配置部分名称为SecurityQuestionsSection
我假设您有以下代码:
public class SecurityQuestionsSection: ConfigurationSection
{
    [ConfigurationProperty("questions", IsRequired = true, IsDefaultCollection = true)]
    public QuestionCollection Questions
    {
        get
        {
            return (QuestionCollection)base["questions"];
        }
    }
}

如果是这样的话,你可以写出类似下面这样的东西:
var customConfigSection = (SecurityQuestionsSection)ConfigurationManager
                                        .GetSection("securityQuestionsSection");

var firstElementId = customConfigSection.Questions[0].Id;  

希望这能帮到您!
编辑:要通过其键访问配置元素,您有两个选项。
1)您可以在类外使用Linq:
var elementWithIdOfThree = customConfigSection.Questions
                                   .FirstOrDefault(item => item.Id == 3);  

2) 或者您可以像这样为您的QuestionCollection类添加一个方法:

public Question GetQuestionWithId(int id)
{
    return this.FirstOrDefault(item => item.Id == id);
}

好的...我有那段代码,但我仍然无法通过关键字customConfigSection.Questions[<HERE_GOES_THE_KEY_NOT_POSITION>].Id访问它。 - Lucas Batistussi
1
@LucasBatistussi,你的意思是想要获取id为“3”的元素吗? - Aleksei Chepovoi
是的!这正是我想要的 :) - Lucas Batistussi
嗯...我得到了一个丑陋的解决方案...我在QuestionCollection类中做了以下操作:public Question this[string idx] { get { object[] keys = this.BaseGetAllKeys(); int IDX = int.Parse(idx); foreach(object i in keys){ if (IDX == (int)i) { return BaseGet(i) as Question; } } return null; }} - Lucas Batistussi
你有更优雅的解决方案吗?ASP.NET 有默认的方法来做这件事吗? - Lucas Batistussi

0
[ConfigurationCollection(typeof(Question))]
public class QuestionCollection : ConfigurationElementCollection
{   

    public override bool IsReadOnly()
    {
        return false;
    }

    protected override ConfigurationElement CreateNewElement()
    {
        return new Question();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((Question)element).id;
    }

    public Question GetQuestion(int id)
    {
        return (Question)this.BaseGet(id);
    }

}

如果您不想使用Linq,可以使用BaseGet。 - WoodsLink

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