Чтение пользовательских разделов конфигурации возвращает «Неверное значение ключа» - PullRequest
10 голосов
/ 14 февраля 2012

У меня проблемы с чтением файла app.config с помощью ConfigurationManager.У меня есть пользовательский раздел, который использует ConfigurationElementCollection.

Мой (урезанный) XML:

<configuration>
    <configSections>
        <sectionGroup name ="CustomerMatching">
            <section name="SearchWeight" type="BLL.Contracts.Helpers.CustomerMatching.SearchWeightSection, BLL.Contracts"/>
        </sectionGroup>
    </configSections>

    <CustomerMatching>
        <SearchWeight>
            <methods>
                <method SearchMethod="ByContactName" Weight="100"/> <!--Line 53, referenced in Error -->
                <method SearchMethod="ByBusinessName" Weight="250"/>
                <method SearchMethod="ByPostcode" Weight="250"/>
                <method SearchMethod="ByMobile" Weight="500"/>
                <method SearchMethod="ByLandline" Weight="500"/>
                <method SearchMethod="ByCompCharNo" Weight="850"/>
            </methods>
        </SearchWeight>
    </CustomerMatching>
</configuration>

Мои классы конфигурации:

public class SearchWeightSection: ConfigurationSection
{
    [ConfigurationProperty("methods", IsRequired = true)]
    [ConfigurationCollection(typeof(SearchMethods), AddItemName = "method", CollectionType =  ConfigurationElementCollectionType.BasicMap)]
    public SearchMethods SearchMethods
    {
        get { return (SearchMethods) base["methods"]; }
    }
}

public class SearchMethods: ConfigurationElementCollection
{
    protected override ConfigurationElement CreateNewElement()
    {
        return new Method();
    }

    protected override object GetElementKey(ConfigurationElement element)
    {
        var method = (Method) element;

        return method.SearchMethod;
    }

    public new Method this[string index]
    {
        get { return (Method)BaseGet(index); }

    }
}

public class Method: ConfigurationElement
{
    [ConfigurationProperty("SearchMethod", IsKey = true, IsRequired = true)]
    public string SearchMethod { get; set; }

    [ConfigurationProperty("Weight", IsRequired = true)]
    public string Weight { get; set; }

    public Method(string searchMethod, string weight)
    {
        SearchMethod = searchMethod;
        Weight = weight;
    }

    public Method()
    {

    }
}

Попытка использоватьэто:

    [TestMethod]
    public void TestConfigReader()
    {
        var searchSection = (SearchWeightSection)ConfigurationManager.GetSection("CustomerMatching/SearchWeight");
        Assert.AreEqual(searchSection.SearchMethods["ByContactName"].Weight, "100");
    }

Моя ошибка:

Test method BLL.UnitTests.Customer.CustomerMatchManagerTest.TestConfigReader threw exception: 
System.Configuration.ConfigurationErrorsException: Invalid key value. (C:\Users\michael\Documents\Visual Studio 2010\MyProject\BLL.UnitTests\bin\Debug\BLL.UnitTests.dll.config line 53)
at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, ref Object result, ref Object resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, ref Object result, ref Object resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, ref Object result, ref Object resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, ref Object result, ref Object resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
at System.Configuration.ConfigurationManager.GetSection(String sectionName)
at BLL.UnitTests.Customer.CustomerMatchManagerTest.TestConfigReader() in CustomerMatchManagerTest.cs: line 41

Спасибо.

1 Ответ

18 голосов
/ 14 февраля 2012

Ваш код выглядит абсолютно нормально, если не считать самого элемента конфигурации метода.

Поскольку это элемент конфигурации, свойства должны хранить данные в коллекции значений имени базового класса (ConfigurationElement). В противном случае ключ и значение не будут инициализированы.

public class Method: ConfigurationElement
{
    [ConfigurationProperty("SearchMethod", IsKey = true, IsRequired = true)]
    public string SearchMethod
    {
        get { return base["SearchMethod"] as string; }
        set { base["SearchMethod"] = value; }
    }

    [ConfigurationProperty("Weight", IsRequired = true)]
    public string Weight
    {
        get { return base["Weight"] as string; }
        set { base["Weight"] = value; }
    }

    //REST OF YOUR CLASS
}

Надеюсь, это поможет.

...