Adding a custom settings section for a module, with user display of view/edit forms

In this article, we show how to add a custom settings section for a module, where you can define the following settings for connecting to an MSSQL Server database: User Name, Password, DataSource, InitialCatalog. To implement a settings section you have to inherit from the following classes:

  1. ELMA.Runtime.Settings.GlobalSettingsBase- base class for global settings, it stores settings in the object.
  2. ELMA.Runtime.Settings.GlobalSettingsModuleBase<TSettings>- this class defines the name of the module, its section in the system, and the methods for loading/saving settings.
  3. ELMA.Web.Mvc.Models.Settings.GlobalSettingsModuleControllerBase<TSettings, TSettingsModule>- this class is needed to define the position of the module’s settings, and to render view/edit forms.

Fig. 1. Module settings

Fig. 1. Module settings

Methods of the GlobalSettingsBase

/// <summary>
/// Receive data on property
/// </summary>
/// <param name="property">Property</param>
/// <returns>Data dictionary</returns>
protected virtual IDictionary<string, string> GetStorageValue(PropertyInfo property)
 
/// <summary>
/// Whether to skip the propery when automatically generating data
/// </summary>
/// <param name="property">Property</param>
/// <returns><c>true</c>, if skip</returns>
protected virtual bool SkipProperty(PropertyInfo property)
 
/// <summary>
/// Define property value according to data dictionary
/// </summary>
/// <param name="property">Property</param>
/// <param name="values">Data dictionary</param>
protected virtual void SetStorageValue(PropertyInfo property, IDictionary<string, string> values)
 
/// <summary>
/// Receive settings from object
/// </summary>
/// <returns>Settings dictionary</returns>
public virtual IDictionary<string, string> GetStorageValues()
 
/// <summary>
/// Set values in the object
/// </summary>
/// <param name="values">Settings dictionary</param>
public virtual void SetStorageValues(IDictionary<string, string> values)
 
/// <summary>
/// Full settings data
/// </summary>
[HiddenInput(DisplayValue = false)]
public virtual IDictionary<string, string> SettingsData

Example of class inherited from GlobalSettingsBase

public class MSSQLConnectionSettings : GlobalSettingsBase
{
    /// <summary>
    /// Determines that the password has not been changed
    /// </summary>
    public const string PASSWORD_NOT_CHANGED = "($PASSWORD_NOT_CHANGED$)";
 
    public MSSQLConnectionSettings()
    {
        DataSource = "(local)";
        InitialCatalog = "BASEMESSAGES";
    }
 
 
    [DisplayName(typeof(@__Resources_MSSQLConnectionSettings), "DataSource")]
    [Description(typeof(@__Resources_MSSQLConnectionSettings), "DataSourceDescription")]
    [Required(true)] //Required field
    public string DataSource { get; set; }
 
    [DisplayName(typeof(@__Resources_MSSQLConnectionSettings), "InitialCatalog")]
    [Description(typeof(@__Resources_MSSQLConnectionSettings), "InitialCatalogDescription")]
    [Required(true)] //Required field
    public string InitialCatalog { get; set; }
 
    [DisplayName(typeof(@__Resources_MSSQLConnectionSettings), "UserId")]
    [Description(typeof(@__Resources_MSSQLConnectionSettings), "UserIdDescription")]
    [Required(true)] //Required field
    public string UserId { get; set; }
 
    [DisplayName(typeof(@__Resources_MSSQLConnectionSettings), "Password")]
    [Description(typeof(@__Resources_MSSQLConnectionSettings), "PasswordDescription")]
    [Required(true)] //Required field
    public string Password
    {
        get { return ServerPassword; }
        set
        {
            if (value != PASSWORD_NOT_CHANGED)
            {
                ServerPassword = value;
            }
        }
    }
 
    private string ServerPassword; 
 
}
 
/// <summary>
/// Resources
/// </summary>
internal class @__Resources_MSSQLConnectionSettings
{
    public static string DataSource { get { return SR.T("DataSource"); } }
 
    public static string DataSourceDescription { get { return SR.T("Connect to base"); } }
 
    public static string InitialCatalog { get { return SR.T("InitialCatalog"); } }
 
    public static string InitialCatalogDescription { get { return SR.T("Database name"); } }
 
    public static string UserId { get { return SR.T("User name"); } }
 
    public static string UserIdDescription { get { return SR.T("User name to connect to database"); } }
 
    public static string Password { get { return SR.T("Password"); } }
 
    public static string PasswordDescription { get { return SR.T("Password to connect to database"); } }
 
}

GlobalSettingsModuleBase class methods

/// <summary>
/// Module name
/// </summary>
public abstract string ModuleName
 
/// <summary>
/// Current typed settings
/// </summary>
public virtual TSettings Settings
 
/// <summary>
/// Save settings
/// </summary>
public virtual void SaveSettings()
 
/// <summary>
/// Module ID
/// </summary>
public abstract Guid ModuleGuid
 
/// <summary>
/// Object with current settings
/// </summary>
object IGlobalSettingsModule.Settings
 
/// <summary>
/// Load settings
/// </summary>
protected virtual void LoadSettings()

Example of class inherited from GlobalSettingsModuleBase

[Component]
public class MSSQLConnectionSettingsModule : GlobalSettingsModuleBase<MSSQLConnectionSettings>
{
    public static Guid UID = new Guid("{7BFF13D5-D31D-4225-8452-0176EF571939}");
         
    public override Guid ModuleGuid
    {
        get { return UID; }
    }
 
    /// <summary>
    /// Module name
    /// </summary>
    public override string ModuleName
    {
        get { return SR.T("Settings for connecting to MSSQL database for messaging"); }
    }
}

GlobalSettingsModuleControllerBase class methods

/// <summary>
/// Define the method to return additional strings
/// </summary>
/// <returns></returns>
protected virtual IEnumerable<RowDriverForModel<TSettings>> GetRows()
 
/// <summary>
/// Current typed module
/// </summary>
public TSettingsModule Module
 
/// <summary>
/// The settings module cannot be <c>null</c>.
/// </summary>
IGlobalSettingsModule IGlobalSettingsModuleController.Module
 
/// <summary>
/// Render for the “read” view
/// </summary>
/// <param name="html">Helper</param>
/// <returns>View</returns>
public virtual MvcHtmlString RenderDisplay(HtmlHelper html)
 
/// <summary>
/// Render for the “edit” view "
/// </summary>
/// <param name="html"> Helper </param>
/// <returns> View </returns>
public virtual MvcHtmlString RenderEdit(HtmlHelper html)

Example of class inherited from GlobalSettingsModuleControllerBase

[Component(Order = 260)]
  public class MSSQLConnectionSettingsModuleController : GlobalSettingsModuleControllerBase<MSSQLConnectionSettings, MSSQLConnectionSettingsModule>
  {
    public MSSQLConnectionSettingsModuleController(MSSQLConnectionSettingsModule module)
      : base(module)
    {
    }
 
    public override MvcHtmlString RenderDisplay(HtmlHelper html)
    {
      return html.Action("View", "Home", new {area = RouteProvider.AreaName});
    }
 
    public override MvcHtmlString RenderEdit(HtmlHelper html)
    {
      return html.Action("Edit", "Home", new { area = RouteProvider.AreaName }); 
    }
  }
Note
In this example, the visualization and editing of settings are implemented as View, Edit. The RenderDisplay(HtmlHelper html) and RenderEdit(HtmlHelper html) methods call the corresponding Home controller methods.

Example of Home controller code:

public MSSQLConnectionSettingsModule SettingsModule { get; set; }</span>public MSSQLConnectionSettings Settings
{
    get
    {
        return SettingsModule.Settings;
    }
}
 
[HttpGet]
public ActionResult View()
{
    return PartialView(Settings);
}
 
[HttpGet]
public ActionResult Edit()
{
    return PartialView(Settings);
}

Example of a View form code: 

@using EleWise.ELMA
@model Permissions.Web.Extensions.MSSQLConnectionSettings
 
@using (Html.TableForm(v => v.ViewType(EleWise.ELMA.Model.Views.ViewType.Display).Attributes(a => a.@class = "settings_table")))
{
    @Html.Property(m => m.DataSource)
    @Html.Property(m => m.InitialCatalog)
    @Html.Property(m => m.UserId)
    <tr>
        <td class="captionCell">@Html.Caption(m => m.Password)</td>
        <td><span class="comment3">@(!String.IsNullOrEmpty(Model.Password) ? SR.T("Set") : SR.T("Not set"))</span></td>
    </tr>
}
​

Example of an Edit form code:

@using EleWise.ELMA
@using EleWise.ELMA.Web.Mvc.Html
@using Permissions.Web.Extensions
@model MSSQLConnectionSettings
 
@using (Html.TableForm(v => v.ViewType(EleWise.ELMA.Model.Views.ViewType.Edit).Attributes(a => a.@class = "settings_table")))
{
    @Html.EditableProperty(m => m.DataSource)
    @Html.EditableProperty(m => m.InitialCatalog)
    @Html.EditableProperty(m => m.UserId)
<tr>
    <td class="captionCell">
        @Html.Caption(m => m.Password, a => a.Required = true)
    </td>
    <td>
        @Html.Hidden("Password", MSSQLConnectionSettings.PASSWORD_NOT_CHANGED)
        <a href="#" onclick="@Html.OpenPopup("SetPasswordPopup");return false;">
            @(string.IsNullOrEmpty(Model.Password) ? SR.T("Set password") : SR.T("Change password"))
        </a>
        @Html.PopupWindow("SetPasswordPopup", SR.T("Set password"), @<div>@Html.Partial("SetPasswordForm")</div>, width: 200)
    </td>
</tr>
}

 

password settings

Fig. 2. Editing settings module

In the Edit form, a pop-up SetPasswordPopup appears to set a password. Below you can see an example of its code:

@using EleWise.ELMA
<div>
  @Html.Password("NewPassword", string.Empty, new { style = "width:100%", TextMode = "Password" })
</div>
<div>
  <div class="popup-buttons">
    <input type="button" class="confirm" value="@SR.T("Save")" onclick="$(’#Password’).val($(’#NewPassword’).val()); @Html.ClosePopup("SetPasswordPopup")" />
    <input type="button" value="@SR.T("Cancel")" onclick="@Html.ClosePopup("SetPasswordPopup")" />
  </div>
</div>

setting up password

Fig. 3. Setting the password 

Note
In this example, we implemented settings for connecting to an MSSQL database with a separate message channel. To use these settings you need to load them and use the received data. Here is an example of using the settings when connecting to an MSSQL database:
public static string MssqlConnectionString()
{
    var settings = Locator.GetService<MSSQLConnectionSettingsModule>();
             
    if (settings.Settings.DataSource.IsNullOrWhiteSpace() ||
        settings.Settings.InitialCatalog.IsNullOrWhiteSpace() ||
        settings.Settings.UserId.IsNullOrWhiteSpace() ||
        settings.Settings.Password.IsNullOrWhiteSpace())
        return string.Empty;
    else
    {
        var connectionstring = new SqlConnectionStringBuilder()
        {
            DataSource = settings.Settings.DataSource,
            InitialCatalog = settings.Settings.InitialCatalog,
            UserID = settings.Settings.UserId,
            Password = settings.Settings.Password
        };
        return connectionstring.ToString();
    }
}
 
public static void SqlQuery(string query, Dictionary<string, object> parameters = null)
{
    if (MssqlConnectionString().IsNullOrWhiteSpace())
        return;
    else
    {
        SqlConnection MssqlConnection = new SqlConnection(MssqlConnectionString());
              
 if (MssqlConnection.State == ConnectionState.Closed) //if the connection is closed, open it
        MssqlConnection.Open();
  
 //Insert your code here
         }
}

Links to API elements

GlobalSettingsBase

GlobalSettingsModuleControllerBase

GlobalSettingsModuleBase

Attachments