Nested/Hierarchical configuration
Compatibility
The content of this page can only be used if the following condition(s) are all met:
- You must target the Vault Application Framework 2.0 or higher.
In some situations, using nested configuration objects may be needed to express complex configuration structures. One such example would be where an application requires the user to configure a collection of rules, similarly to the Metadata Card Configuration. The sample below defines two configuration classes (Configuration
and ConfigurationChild
). Members exposed by either configuration class could be simple strings (as below), or any other configuration value for which an editor exists.
Using nested configuration
using System.Collections.Generic;
using System.Runtime.Serialization;
using MFiles.VAF;
using MFiles.VAF.AdminConfigurations;
namespace MFVaultApplication1
{
[DataContract]
public class Configuration
{
[DataMember]
public ConfigurationChild MySubConfiguration { get; set; }
[DataMember]
public List<ConfigurationChild> Children { get; set; }
}
[DataContract]
public class ConfigurationChild
{
[DataMember]
public string Value1 { get; set; }
}
public class VaultApplication
: ConfigurableVaultApplicationBase<Configuration>
{
}
}
Array Element Guid
When working with collections it is important that each collection member has an ID which can be used to subsequently refer to the member. This is used when saving the configuration, for example, to understand what has changed. If you do not include this member then the system may not correctly persist passwords, or may require system-administrator permission to save the configuration, even if only vault-admin level is required for the changed elements.
This can be done in two ways: either by adding a member to the class in the collection, or by inheriting from the ConfigurationCollectionItemBase class in the VAF Extensions library.
Using the VAF Extensions
Ensure that your configuration item class inherits from the correct base class:
[DataContract]
public class Configuration
{
[DataMember]
public ConfigurationChild MySubConfiguration { get; set; }
[DataMember]
public List<ConfigurationChild> Children { get; set; }
}
[DataContract]
public class ConfigurationChild
: MFiles.VAF.Extensions.Configuration.ConfigurationCollectionItemBase
{
[DataMember]
public string Value1 { get; set; }
[DataMember]
[TextEditor(IsRequired = true)]
public string Name { get; set; }
}
public class VaultApplication
: ConfigurableVaultApplicationBase<Configuration>
{
}
Implementing manually
Add an item to the class with the following signature (arrayElementGuid
):
[DataContract]
public class Configuration
{
[DataMember]
public ConfigurationChild MySubConfiguration { get; set; }
[DataMember]
public List<ConfigurationChild> Children { get; set; }
}
[DataContract]
public class ConfigurationChild
{
[DataMember]
public string Value1 { get; set; }
[DataMember]
[TextEditor(IsRequired = true)]
public string Name { get; set; }
[DataMember(Name = "arrayElementGuid", EmitDefaultValue = false, Order = 99)]
[JsonConfEditor
(
TypeEditor = "guid",
Hidden = true,
IsRequired = true,
ClearOnCopy = true
)]
public string ArrayElementGuid { get; set; }
= System.Guid.NewGuid().ToString();
}
public class VaultApplication
: ConfigurableVaultApplicationBase<Configuration>
{
}
Customising array element names
In the example screenshot above, adding new items to the Children
collection results in items being added named ConfigurationChild[1]
, ConfigurationChild[1]
, etc. In some situations, it is more useful to show a different value for the item name to make locating the correct item more simple.
This can be done by ensuring that the class in question (ConfigurationChild
, below) exposes a Name
property:
using System.Collections.Generic;
using System.Runtime.Serialization;
using MFiles.VAF;
using MFiles.VAF.AdminConfigurations;
namespace MFVaultApplication1
{
[DataContract]
public class Configuration
{
[DataMember]
public ConfigurationChild MySubConfiguration { get; set; }
[DataMember]
public List<ConfigurationChild> Children { get; set; }
}
[DataContract]
public class ConfigurationChild
{
[DataMember]
public string Value1 { get; set; }
[DataMember]
[TextEditor(IsRequired = true)]
public string Name { get; set; }
[DataMember(Name = "arrayElementGuid", EmitDefaultValue = false, Order = 99)]
[JsonConfEditor
(
TypeEditor = "guid",
Hidden = true,
IsRequired = true,
ClearOnCopy = true
)]
public string ArrayElementGuid { get; set; }
= System.Guid.NewGuid().ToString();
}
public class VaultApplication
: ConfigurableVaultApplicationBase<Configuration>
{
}
}
Alternatively, if the name should be derived from a different property then it can declared using the JsonConfEditor
attribute on the class itself. In the case of the example below, the NameProperty
property has been explicitly marked as the property to use for the object names.
using System.Collections.Generic;
using System.Runtime.Serialization;
using MFiles.VAF;
using MFiles.VAF.AdminConfigurations;
namespace MFVaultApplication1
{
[DataContract]
public class Configuration
{
[DataMember]
public ConfigurationChild MySubConfiguration { get; set; }
[DataMember]
public List<ConfigurationChild> Children { get; set; }
}
[DataContract]
[JsonConfEditor(NameMember = "NameProperty")]
public class ConfigurationChild
{
[DataMember]
public string Value1 { get; set; }
[DataMember]
[TextEditor(IsRequired = true)]
public string NameProperty { get; set; }
[DataMember(Name = "arrayElementGuid", EmitDefaultValue = false, Order = 99)]
[JsonConfEditor
(
TypeEditor = "guid",
Hidden = true,
IsRequired = true,
ClearOnCopy = true
)]
public string ArrayElementGuid { get; set; }
= System.Guid.NewGuid().ToString();
}
public class VaultApplication
: ConfigurableVaultApplicationBase<Configuration>
{
}
}