Нередко перед разработчиком стоит задача создания настройки для хранения пути к папкам на сервере, например, папкам для импорта / экспорта тел документов в систему / из системы. Безусловно, можно показать администратору системы простейший диалог с одним текстовым полем, в которое последний вставит путь, скопированный вручную, и сохранить результат диалога в таблицу с параметрами Sungero_Docflow_Params стандартным способом. Но такой подход не назовешь образчиком дружелюбного интерфейса на мой взгляд. К сожалению, показать полноценный диалог выбора папки невозможно из-за ограничений, налагаемых веб-браузером.
Столкнувшись с данной проблемой, я нашел свой немудреный подход, которым и спешу поделиться. Хотя в коде и используется запрещенный класс System.IO, но нанести какой-то вред файловой системе сервера, или дискредитировать какие-то данные таким образом, на мой взгляд, невозможно, ведь производится всего лишь чтение имен папок на сервере (имена файлов в директории не отображаются). При этом учитываются права доступа к папкам. К тому же доступ к подобному функционалу обычно ограничивается средствами самого RX и предоставляется только участникам группы "Администраторы". Работу с нелегалом System.IO необходимо вынести в изолированную область.
Приведенный ниже код позволяет довольно удобно совершать навигацию по папкам сервера, начиная от выбора диска до самых нижних папок в иерархии, где вложенные папки уже отсутствуют. Кнопка «<<» (назад) поднимает выбор по иерархии выше в родительскую папку. При закрытии диалога по кнопке «Ок» выбранный путь сохраняется в таблице с параметрами. Сам диалог был реализован мной в функции обложки модуля в разделе "Настройки".
Следует оговорить ограничения использования данного диалога серверами под управлением операционной системой Windows. Так же стоит упомянуть, что для системы, развернутой на кластере, необходимо учитывать актуальность заданных в настойке путей для всех узлов в кластере.
var param = Sungero.Docflow.PublicFunctions.Module.Remote.GetDocflowParamsStringValue(Constants.Module.TimeSheetInputFolderPath);
var dialog = Dialogs.CreateInputDialog("Папка экспорта Табелей учета рабочего времени");
var drives = IsolatedFunctions.SystemIO.GetDrives().ToArray();
dialog.Width = 500;
var pathString = dialog.AddString(string.Empty, false);
pathString.IsEnabled = false;
pathString.Value = param;
var folderPath = dialog.AddSelect(string.Empty, false);
var back = dialog.Buttons.AddCustom("<<");
dialog.Buttons.AddCancel();
dialog.Buttons.AddOk();
folderPath.SetOnValueChanged((x) => {pathString.Value = x.NewValue;});
dialog.SetOnRefresh((x) =>
{
if (string.IsNullOrEmpty(pathString.Value))
folderPath.From(drives);
else
{
// обработка исключения при отсутствии прав доступа к папке
try
{
folderPath.From(IsolatedFunctions.SystemIO.GetDirectories(pathString.Value).ToArray());
}
catch (Exception e)
{
x.AddError(e.Message);
}
}
}
);
dialog.SetOnButtonClick((d) =>
{
if (d.Button == back)
{
var lastSlashIndex = pathString.Value.LastIndexOf('\\');
if (pathString.Value.Length == 3)
pathString.Value = string.Empty;
else if (lastSlashIndex == 2)
pathString.Value = pathString.Value.Substring(0, lastSlashIndex + 1);
else
pathString.Value = pathString.Value.Substring(0, lastSlashIndex);
d.CloseAfterExecute = false;
}
if (d.Button == DialogButtons.Ok)
{
Sungero.Docflow.PublicFunctions.Module.InsertOrUpdateDocflowParam(Constants.Module.TimeSheetInputFolderPath, pathString.Value);
}
}
);
dialog.Show();
В изолированной области модуля необходимо добавить две функции для работы с классом System.IO
public class IsolatedFunctions
{
[Public]
public static List<string> GetDrives()
{
return System.IO.DriveInfo.GetDrives().Select(d => d.Name).ToList();
}
[Public]
public static List<string> GetDirectories(string path)
{
return System.IO.Directory.GetDirectories(path).ToList();
}
}
Авторизуйтесь, чтобы написать комментарий