Можно ли сделать эту индивидуальную конфигурацию?

Вот моя структура xml:

<reco>
    <styleSheets>
      <group>
        <asset source="~/Script/file1.css"/>
        <asset source="~/Script/file2.css"/>
        <asset source="~/Script/file3.css"/>
    </group>
  </styleSheets>
  <scripts>
    <group>
        <asset source="~/Content/file1.js"/>
        <asset source="~/Content/file1.js"/>
        <asset source="~/Content/file1.js"/>
    </group>
  </scripts>

Here is my code:

public class AssetConfigurationElement : ConfigurationElement
{

    /// <summary>
    /// Gets or sets the source.
    /// </summary>
    /// <value>The source.</value>
    [ConfigurationProperty("source", IsRequired = true, IsKey = true)]
    public string Source
    {
        get
        {
            return (string)this["source"];
        }

        set
        {
            this["source"] = value;
        }
    }
}

public class GroupConfigurationElementCollection : ConfigurationElementCollection
{
    public GroupConfigurationElementCollection()
    {
        AddElementName = "asset";
    }

    /// <summary>
    /// Gets or sets the name.
    /// </summary>
    /// <value>The name.</value>
    [ConfigurationProperty("name", IsRequired = true, IsKey = true, IsDefaultCollection = true)]
    public string Name
    {
        get
        {
            return (string)this["name"];
        }

        set
        {
            this["name"] = value;
        }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="WebAssetGroupConfigurationElement"/> is enabled.
    /// </summary>
    /// <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
    [ConfigurationProperty("enabled", DefaultValue = true)]
    public bool Enabled
    {
        get
        {
            return (bool)this["enabled"];
        }

        set
        {
            this["enabled"] = value;
        }
    }

    /// <summary>
    /// Gets or sets the version.
    /// </summary>
    /// <value>The version.</value>
    [ConfigurationProperty("version")]
    public string Version
    {
        get
        {
            return (string)this["version"];
        }

        set
        {
            this["version"] = value;
        }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="WebAssetGroupConfigurationElement"/> is compress.
    /// </summary>
    /// <value><c>true</c> if compress; otherwise, <c>false</c>.</value>
    [ConfigurationProperty("compress", DefaultValue = true)]
    public bool Compress
    {
        get
        {
            return (bool)this["compress"];
        }

        set
        {
            this["compress"] = value;
        }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="WebAssetGroupConfigurationElement"/> is combined.
    /// </summary>
    /// <value><c>true</c> if combined; otherwise, <c>false</c>.</value>
    [ConfigurationProperty("combined", DefaultValue = true)]
    public bool Combined
    {
        get
        {
            return (bool)this["combined"];
        }

        set
        {
            this["combined"] = value;
        }
    }


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

    protected override object GetElementKey(ConfigurationElement element)
    {
        return ((AssetConfigurationElement)element).Source;
    }

}

public class SharedGroupConfigurationSection : ConfigurationSection
{

    /// <summary>
    /// Gets the style sheets.
    /// </summary>
    /// <value>The style sheets.</value>
    [ConfigurationProperty("styleSheets")]
    [ConfigurationCollection(typeof(GroupConfigurationElementCollection), AddItemName = "group")]
    public GroupConfigurationElementCollection StyleSheets
    {
        get
        {
            return (GroupConfigurationElementCollection)base["styleSheets"] ?? new GroupConfigurationElementCollection();
        }
    }

    /// <summary>
    /// Gets the style sheets.
    /// </summary>
    /// <value>The style sheets.</value>
    [ConfigurationProperty("scripts")]
    [ConfigurationCollection(typeof(GroupConfigurationElementCollection), AddItemName = "group")]
    public GroupConfigurationElementCollection Scripts
    {
        get
        {
            return (GroupConfigurationElementCollection)base["scripts"] ?? new GroupConfigurationElementCollection();
        }
    }
}

Возможна ли вообще такая конфигурация? Если да, то что я делаю не так?

Я получаю это сообщение об ошибке, когда пытаюсь получить раздел с менеджером конфигурации.

Описание ошибки конфигурации: ошибка произошла во время обработки файла конфигурации, необходимого для обслуживания этого запроса. Просмотрите приведенные ниже сведения о конкретных ошибках и соответствующим образом измените файл конфигурации.

Сообщение об ошибке парсера: Неизвестный элемент «актив».

Ошибка источника:

Строка 96: Строка 97: Строка 98: Строка 99: Строка 100:

Исходный файл: D: \ ASP.NET Projects \ Resource-Compiler \ ResourceCompiler \ Examples \ web.config Строка: 98


person user1139554    schedule 06.05.2012    source источник
comment
вы должны увидеть и использовать Cassete вместо того, чтобы делать что-то с нуля ... плюс, это поддерживает гораздо больше. попробуйте!   -  person balexandre    schedule 06.05.2012


Ответы (3)


Как я вижу, вы пытаетесь вставить настраиваемый раздел в «стандартный» файл web.config. В этом случае вам необходимо зарегистрировать свой кастомный раздел в

<configSections>

и добавьте туда соответствующий раздел. Например (это некий конфиг Quartz в одном из моих проектов):

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <configSections>

        <sectionGroup name="common">
            <section name="logging" type="Common.Logging.ConfigurationSectionHandler, Common.Logging" />
        </sectionGroup>
        ... other sections here...
    </configSections>
    ... other web.config stuff here

а затем где-то ниже вам нужно добавить свой собственный раздел, например:

<common>
    <logging>
        <factoryAdapter type="Common.Logging.Log4Net.Log4NetLoggerFactoryAdapter, Common.Logging.Log4net">
            <arg key="configType" value="INLINE" />
        </factoryAdapter>
    </logging>
</common>

Вот статья msdn по этой теме: http://msdn.microsoft.com/en-us/library/2tw134k3.aspx

person Mikhail    schedule 06.05.2012

Так и должно быть, но вам нужен именной тег для каждого актива, поскольку он является обязательным атрибутом для каждого актива. Если вам это не нужно, удалите из него IsRequired = true и IsKey = true. ConfigurationElementCollection накладывает строгие требования к формату ваших данных в App.Config. Система Sytem.Configuration позволяет наследовать значения из родительского файла app.config. Это работает даже для коллекций объектов. Чтобы это работало, дизайнер MS ввел специальные теги.

Чтобы удалить все элементы из коллекции, загруженной из родительского app.config, был добавлен тег <clear/>.

Чтобы добавить элемент, вам понадобится тег <add/>, в котором данные разделены на свойства. Тогда ваш app.config должен выглядеть так

<add asset source="~/Script/file1.css"/>

Чтобы поддержать наследование конфигурации, вы платите цену за довольно заблокированный формат сериализации, которого вы должны придерживаться. Конечно, вы можете расширить систему и добавить своего собственного поставщика конфигурации, который сделает это по-другому, но это непростая задача. По крайней мере, намного сложнее, чем использовать настоящий сериализатор, такой как XmlSerializer, где у вас есть наибольшая свобода в выборе формата данных.

DataContractSerializer тоже хорош, но не позволяет вам все контролировать. XmlSerializer по-прежнему остается самым быстрым и универсальным сериализатором для файлов xml.

person Alois Kraus    schedule 06.05.2012

Я смог заставить его работать. Мне пришлось добавить две новые коллекции для узла таблицы стилей и узла сценария. Вот мой полный код:

    public class SharedGroupConfigurationSection : ConfigurationSection
{

    /// <summary>
    /// Gets the style sheets.
    /// </summary>
    /// <value>The style sheets.</value>
    [ConfigurationProperty("styleSheets", Options = ConfigurationPropertyOptions.IsRequired)]        
    public StyleSheetConfigurationElementCollection StyleSheets
    {
        get
        {
            return (StyleSheetConfigurationElementCollection)base["styleSheets"] ?? new StyleSheetConfigurationElementCollection();
        }
    }

    /// <summary>
    /// Gets the style sheets.
    /// </summary>
    /// <value>The style sheets.</value>
    [ConfigurationProperty("scripts", Options = ConfigurationPropertyOptions.IsRequired)]        
    public ScriptConfigurationElementCollection Scripts
    {
        get
        {
            return (ScriptConfigurationElementCollection)base["scripts"] ?? new ScriptConfigurationElementCollection();
        }
    }
}


[ConfigurationCollection(typeof(GroupConfigurationElementCollection), AddItemName = "group")]
public class ScriptConfigurationElementCollection : ConfigurationElementCollection
{

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

    protected override object GetElementKey(ConfigurationElement element)
    {
        if (element == null)
        {
            throw new ArgumentNullException();
        }

        return ((GroupConfigurationElementCollection)element).Name;
    }
}

[ConfigurationCollection(typeof(GroupConfigurationElementCollection), AddItemName="group")]
public class StyleSheetConfigurationElementCollection : ConfigurationElementCollection
{

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

    protected override object GetElementKey(ConfigurationElement element)
    {
        if (element == null)
        {
            throw new ArgumentNullException();
        }

        return ((GroupConfigurationElementCollection)element).Name;
    }
}

[ConfigurationCollection(typeof(AssetConfigurationElement), AddItemName = "asset", CollectionType = ConfigurationElementCollectionType.BasicMap)]
public class GroupConfigurationElementCollection : ConfigurationElementCollection
{
    public GroupConfigurationElementCollection()
    {
        AddElementName = "asset";
    }

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

    protected override object GetElementKey(ConfigurationElement element)
    {
        if (element == null)
        {
            throw new ArgumentNullException();
        }

        return ((AssetConfigurationElement)element).Source;
    }

    /// <summary>
    /// Gets or sets the name.
    /// </summary>
    /// <value>The name.</value>
    [ConfigurationProperty("name", IsRequired = true)]
    public string Name 
    {
        get
        {
            return (string)base["name"];
        }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="WebAssetGroupConfigurationElement"/> is enabled.
    /// </summary>
    /// <value><c>true</c> if enabled; otherwise, <c>false</c>.</value>
    [ConfigurationProperty("enabled", DefaultValue = true)]
    public bool Enabled
    {
        get
        {
            return (bool)this["enabled"];
        }

        set
        {
            this["enabled"] = value;
        }
    }

    /// <summary>
    /// Gets or sets the version.
    /// </summary>
    /// <value>The version.</value>
    [ConfigurationProperty("version")]
    public string Version
    {
        get
        {
            return (string)this["version"];
        }

        set
        {
            this["version"] = value;
        }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="WebAssetGroupConfigurationElement"/> is compress.
    /// </summary>
    /// <value><c>true</c> if compress; otherwise, <c>false</c>.</value>
    [ConfigurationProperty("compress", DefaultValue = true)]
    public bool Compress
    {
        get
        {
            return (bool)this["compress"];
        }

        set
        {
            this["compress"] = value;
        }
    }

    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="WebAssetGroupConfigurationElement"/> is combined.
    /// </summary>
    /// <value><c>true</c> if combined; otherwise, <c>false</c>.</value>
    [ConfigurationProperty("combined", DefaultValue = true)]
    public bool Combined
    {
        get
        {
            return (bool)this["combined"];
        }

        set
        {
            this["combined"] = value;
        }
    }
}

public class AssetConfigurationElement : ConfigurationElement
{

    /// <summary>
    /// Gets or sets the source.
    /// </summary>
    /// <value>The source.</value>
    [ConfigurationProperty("source", IsRequired = false, IsKey = false)]
    public string Source
    {
        get
        {
            return (string)this["source"];
        }

        set
        {
            this["source"] = value;
        }
    }
}
person user1139554    schedule 07.05.2012