我希望能够为以下配置建模:
<bundles>
<resource type="script">
<bundle name="common/services">
<file path="common/consoleService.js" />
<file path="common/localStorageService.js" />
<file path="common/restService.js" />
<!-- ... More files ... -->
</bundle>
</resource>
</bundles>
所以我继续创建以下ConfigurationSection
:
internal class BundlesSection : ConfigurationSection
{
internal const string TAG_NAME = "bundles";
[ConfigurationProperty(ResourceCollection.TAG_NAME,
IsRequired = false,
IsDefaultCollection = true)]
internal ResourceCollection Resources
{
get { return this[ResourceCollection.TAG_NAME] as ResourceCollection; }
}
}
[ConfigurationCollection(typeof(ResourceElement),
AddItemName = ResourceElement.TAG_NAME)]
internal class ResourceCollection : ConfigurationElementCollection
{
internal const string TAG_NAME = "";
protected override ConfigurationElement CreateNewElement()
{
return new ResourceElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((ResourceElement)element).Type;
}
}
[ConfigurationCollection(typeof(BundleElement),
AddItemName = BundleElement.TAG_NAME)]
internal class ResourceElement : ConfigurationElementCollection
{
internal const string TAG_NAME = "resource";
private const string ATTR_TYPE = "type";
[ConfigurationProperty(ATTR_TYPE,
IsRequired = true,
IsKey = true)]
internal string Type
{
get { return this[ATTR_TYPE] as string; }
set { this[ATTR_TYPE] = value; }
}
protected override ConfigurationElement CreateNewElement()
{
return new BundleElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((BundleElement)element).Name;
}
}
[ConfigurationCollection(typeof(FileElement),
AddItemName = FileElement.TAG_NAME)]
internal class BundleElement : ConfigurationElementCollection
{
internal const string TAG_NAME = "bundle";
private const string ATTR_NAME = "name";
[ConfigurationProperty(ATTR_NAME,
IsRequired = true,
IsKey = true)]
internal string Name
{
get { return this[ATTR_NAME] as string; }
set { this[ATTR_NAME] = value; }
}
protected override ConfigurationElement CreateNewElement()
{
return new FileElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((FileElement)element).Path;
}
}
internal class FileElement : ConfigurationElement
{
internal const string TAG_NAME = "file";
private const string ATTR_PATH = "path";
[ConfigurationProperty(ATTR_PATH,
IsRequired = true,
IsKey = true)]
internal string Path
{
get { return this[ATTR_PATH] as string; }
set { this[ATTR_PATH] = value; }
}
}
虽然一切似乎都没问题,但我在第一次加载该部分时遇到以下异常:
无法识别的元素'包'
正如您所看到的,BundleElement.TAG_NAME
是"bundle"
,所以我不知道为什么它不被识别。
我正在加载配置部分,如下所示:
private BundlesSection LoadSection()
{
return ConfigurationManager.GetSection(String.Format("static/{0}", BundlesSection.TAG_NAME)) as BundlesSection;
}
我的Web.config
:
<configuration>
<configSections>
<sectionGroup name="static">
<section name="bundles" type="XXX" restartOnExternalChanges="true" />
</sectionGroup>
</configSections>
<static>
<bundles configSource=".\Configuration\Static\Bundles.xml" />
</static>
</configuration>
答案 0 :(得分:1)
两个问题:集合类型和元素名称。需要将ResourceElement和BundleElement指定为ConfigurationElementCollectionType.BasicMap
然后适当地覆盖它们各自的ElementName属性。
[ConfigurationCollection(typeof(BundleElement))]
internal class ResourceElement : ConfigurationElementCollection
{
internal const string TAG_NAME = "resource";
private const string ATTR_TYPE = "type";
[ConfigurationProperty(ATTR_TYPE, IsRequired = true, IsKey = true)]
internal string Type
{
get { return base[ATTR_TYPE] as string; }
set { base[ATTR_TYPE] = value; }
}
protected override string ElementName { get { return BundleElement.TAG_NAME; } }
public override ConfigurationElementCollectionType CollectionType
{
get {return ConfigurationElementCollectionType.BasicMap;}
}
protected override ConfigurationElement CreateNewElement()
{
return new BundleElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((BundleElement)element).Name;
}
}
[ConfigurationCollection(typeof(FileElement))]
internal class BundleElement : ConfigurationElementCollection
{
internal const string TAG_NAME = "bundle";
private const string ATTR_NAME = "name";
[ConfigurationProperty(ATTR_NAME, IsRequired = true, IsKey = true)]
internal string Name
{
get { return this[ATTR_NAME] as string; }
set { this[ATTR_NAME] = value; }
}
protected override string ElementName { get { return FileElement.TAG_NAME; } }
public override ConfigurationElementCollectionType CollectionType
{
get { return ConfigurationElementCollectionType.BasicMap; }
}
protected override ConfigurationElement CreateNewElement()
{
return new FileElement();
}
protected override object GetElementKey(ConfigurationElement element)
{
return ((FileElement)element).Path;
}
}