Добавление собственного раздела настроек для модуля с пользовательским отображением формы просмотра и редактирования

В статье приведен пример добавления собственного раздела настроек для модуля, в котором задаются настройки подключения к СУБД MSSQL Server, а именно: Имя пользователя, Пароль, DataSource, InitialCatalog. Для реализации собственного раздела настроек необходимо наследоваться от классов:

  1. EleWise.ELMA.Runtime.Settings.GlobalSettingsBase - Базовый класс для глобальных настроек, хранит настройки в полях объекта.
  2. EleWise.ELMA.Runtime.Settings.GlobalSettingsModuleBase<TSettings> - В данном классе определяется название модуля, его раздел в системе, а также для загрузки/сохранения настроек.
  3. EleWise.ELMA.Web.Mvc.Models.Settings.GlobalSettingsModuleControllerBase<TSettings, TSettingsModule> - Данный класс необходим для определения положения настроек модуля, а также для отрисовки форм просмотра/редактирования.

Пример отображения данных

Рис. 1. Раздел настроек для модуля

Методы класса GlobalSettingsBase

/// <summary>
/// Получить данные по свойству
/// </summary>
/// <param name="property">Свойство</param>
/// <returns>Словарь с данными</returns>
protected virtual IDictionary<string, string> GetStorageValue(PropertyInfo property)

/// <summary>
/// Пропускать ли свойство при автоматическом формировании данных
/// </summary>
/// <param name="property">Свойство</param>
/// <returns><c>true</c>, если пропускать</returns>
protected virtual bool SkipProperty(PropertyInfo property)

/// <summary>
/// Установить значение свойства по словарю с данными
/// </summary>
/// <param name="property">Свойство</param>
/// <param name="values">Словарь с данными</param>
protected virtual void SetStorageValue(PropertyInfo property, IDictionary<string, string> values)

/// <summary>
/// Получить настройки из объекта
/// </summary>
/// <returns>Словарь с настройками</returns>
public virtual IDictionary<string, string> GetStorageValues()

/// <summary>
/// Установить настройки в объект
/// </summary>
/// <param name="values">Словарь с настройками</param>
public virtual void SetStorageValues(IDictionary<string, string> values)

/// <summary>
/// Полные данные настроек
/// </summary>
[HiddenInput(DisplayValue = false)]
public virtual IDictionary<string, string> SettingsData

Пример класса, наследованного от класса GlobalSettingsBase

public class MSSQLConnectionSettings : GlobalSettingsBase
{
    /// <summary>
    /// Определяет, что пароль не изменен
    /// </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)] //Обязательность заполнения поля
    public string DataSource { get; set; }

    [DisplayName(typeof(@__Resources_MSSQLConnectionSettings), "InitialCatalog")]
    [Description(typeof(@__Resources_MSSQLConnectionSettings), "InitialCatalogDescription")]
    [Required(true)] //Обязательность заполнения поля
    public string InitialCatalog { get; set; }

    [DisplayName(typeof(@__Resources_MSSQLConnectionSettings), "UserId")]
    [Description(typeof(@__Resources_MSSQLConnectionSettings), "UserIdDescription")]
    [Required(true)] //Обязательность заполнения поля
    public string UserId { get; set; }

    [DisplayName(typeof(@__Resources_MSSQLConnectionSettings), "Password")]
    [Description(typeof(@__Resources_MSSQLConnectionSettings), "PasswordDescription")]
    [Required(true)] //Обязательность заполнения поля
    public string Password
    {
        get { return ServerPassword; }
        set
        {
            if (value != PASSWORD_NOT_CHANGED)
            {
                ServerPassword = value;
            }
        }
    }

    private string ServerPassword; 

}

/// <summary>
/// Ресурсы
/// </summary>
internal class @__Resources_MSSQLConnectionSettings
{
    public static string DataSource { get { return SR.T("DataSource"); } }

    public static string DataSourceDescription { get { return SR.T("Коннект до базы"); } }

    public static string InitialCatalog { get { return SR.T("InitialCatalog"); } }

    public static string InitialCatalogDescription { get { return SR.T("Имя базы данных"); } }

    public static string UserId { get { return SR.T("Имя пользователя"); } }

    public static string UserIdDescription { get { return SR.T("Имя пользователя для подключения к БД"); } }

    public static string Password { get { return SR.T("Пароль"); } }

    public static string PasswordDescription { get { return SR.T("Пароль для подключения к БД"); } }

}

Методы класса GlobalSettingsModuleBase

/// <summary>
/// Название модуля
/// </summary>
public abstract string ModuleName

/// <summary>
/// Текущие типизированные настройки
/// </summary>
public virtual TSettings Settings

/// <summary>
/// Сохранить настройки
/// </summary>
public virtual void SaveSettings()

/// <summary>
/// Идентификатор модуля
/// </summary>
public abstract Guid ModuleGuid

/// <summary>
/// Объект с текущими настройками
/// </summary>
object IGlobalSettingsModule.Settings

/// <summary>
/// Загрузить настройки
/// </summary>
protected virtual void LoadSettings()

Пример класса, наследованного от класса 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>
    /// Название модуля
    /// </summary>
    public override string ModuleName
    {
        get { return SR.T("Настройки подключения к базе MSSQL для отправки сообщений"); }
    }
}

Методы класса GlobalSettingsModuleControllerBase

/// <summary>
/// Переопределите данный метод для возвращения дополнительных строк
/// </summary>
/// <returns></returns>
protected virtual IEnumerable<RowDriverForModel<TSettings>> GetRows()

/// <summary>
/// Текущий типизированный модуль
/// </summary>
public TSettingsModule Module

/// <summary>
/// Связанный модуль с настройками, не может быть <c>null</c>.
/// </summary>
IGlobalSettingsModule IGlobalSettingsModuleController.Module

/// <summary>
/// Рендер представления "для чтения"
/// </summary>
/// <param name="html">Хелпер</param>
/// <returns>Представление</returns>
public virtual MvcHtmlString RenderDisplay(HtmlHelper html)

/// <summary>
/// Рендер представления "для редактирования"
/// </summary>
/// <param name="html">Хелпер</param>
/// <returns>Представление</returns>
public virtual MvcHtmlString RenderEdit(HtmlHelper html)

Пример класса, наследованного от класса 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 }); 
    }
  }
Примечание
В данном примере отображение настроек и их редактирование реализовано в виде представлений View, Edit. Методы RenderDisplay(HtmlHelper html) и RenderEdit(HtmlHelper html) вызывают соответствующие методы в контроллере Home.

Пример кода контроллера Home:

public MSSQLConnectionSettingsModule SettingsModule { get; set; }</span><br>public MSSQLConnectionSettings Settings
{
    get
    {
        return SettingsModule.Settings;
    }
}

[HttpGet]
public ActionResult View()
{
    return PartialView(Settings);
}

[HttpGet]
public ActionResult Edit()
{
    return PartialView(Settings);
}

Пример кода представления View:

@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("Установлен") : SR.T("Не задан"))</span></td>
    </tr>
}

Пример кода представления Edit:

@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("Установить пароль") : SR.T("Изменить пароль"))
        </a>
        @Html.PopupWindow("SetPasswordPopup", SR.T("Установка пароля"), @<div>@Html.Partial("SetPasswordForm")</div>, width: 200)
    </td>
</tr>
}

Рис. 2. Редактирование настроек модуля

В представлении Edit вызывается popup-окно SetPasswordPopup для установки пароля, пример кода которого представлен ниже:

@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("Сохранить")" onclick="$(’#Password’).val($(’#NewPassword’).val()); @Html.ClosePopup("SetPasswordPopup")" />
    <input type="button" value="@SR.T("Отмена")" onclick="@Html.ClosePopup("SetPasswordPopup")" />
  </div>
</div>

Рис. 3. Установка пароля в поле «Пароль»

Примечание

В данном примере реализованы настройки для подключения к СУБД MSSQL, в которой реализован собственный канал сообщений. Чтобы использовать данные настройки, необходимо их загрузить и использовать полученные данные. Пример использования настроек при подключении к СУБД MSSQL:

 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) //если соединение закрыто - откроем его
        MssqlConnection.Open();
 
 //Дальнейший ваш код
         }
}

Ссылки на элементы API

GlobalSettingsBase

GlobalSettingsModuleControllerBase

GlobalSettingsModuleBase

Прикрепленные файлы