Перейти к содержанию

Загрузка виртуального файла на клиенте без добавления его в карточку

Загрузка виртуального файла на клиенте без добавления его в карточку

Рассмотрим ситуацию, когда на клиенте при нажатии на кнопку или плитку требуется загрузить виртуальный или физический файл, который не приложен к текущей карточке, причём файл может иметь отношение к другой карточке с заданным идентификатором.

Файл должен быть загружен во временную папку, из которой он будет удалён только при обновлении или закрытии текущей карточки.

Для этого напишем вспомогательный метод, который асинхронно загружает файл с заданными параметрами и возвращает путь ко временному файлу или null, если файл загрузить не удалось.

using System; using System.IO; using System.Threading.Tasks; using Tessa.Cards; using Tessa.Files; using Tessa.Platform.Validation; using Tessa.UI; using Tessa.UI.Cards;

namespace Tessa.Extensions.Client { public static class FileExtensionHelper { public static async Task<string> TryLoadVirtualFile( ICardFileManager cardFileManager, ICardModel cardModel, string fileName, Guid cardID, Guid cardTypeID, Guid fileID, Guid versionID) { // cardModel для файлового кэша, из которого временный файл попытается удалиться // после рефреша или закрытия вкладки с карточкой

// создаём псевдо-карточку с заданным идентификатором, и произвольными TypeName/TypeCaption var fakeCard = new Card { ID = cardID, TypeID = cardTypeID, TypeName = CardHelper.FileTypeName, TypeCaption = CardHelper.FileTypeCaption, };

// создаём псевдофайл ICardFileContainer container = cardFileManager.CreateContainer(fakeCard);

IFile file = container.FileContainer .BuildFile(fileName) .SetFileToken(x => x.ID = fileID) .SetVersionToken(x => x.ID = versionID) .SetContent(Stream.Null) .Return(out ValidationResult buildResult);

TessaDialog.ShowNotEmpty(buildResult); if (!buildResult.IsSuccessful) { return null; }

// создаём временный файл, в который будет записан контент IFileContent tempContent = cardModel.FileContainer.Source.Cache.Allocate(fileName); if (!tempContent.IsLocal) { throw new InvalidOperationException("Content isn't local when allocating from cache."); }

string tempPath = tempContent.GetLocalFilePath();

// асинхронно загружаем содержимое файла и сохраняем его в tempPath; // при загрузке не будут учитываться токены KrToken var target = System.IO.File.Create(tempPath); IFileContentResponse loadResponse = await UIHelper.InvokeAsync(() => { var request = new FileContentRequest(file.Versions.Last) { ProcessContentAction = p => p .CopyTo(target) }; return container.FileContainer.Source.GetContent(request); });

TessaDialog.ShowNotEmpty(loadResponse.ValidationResult); return loadResponse.ValidationResult.IsSuccessful ? tempPath : null; } } }

Пример расширения в карточке “Автомобиль”, которое пытается загрузить файл с некоторыми заданными идентификаторами, и в случае успеха файл открывается вызовом Process.Start().

using System; using Tessa.Cards; using Tessa.UI; using Tessa.UI.Cards; using Tessa.UI.Cards.Controls; using Unity;

namespace Tessa.Extensions.Client { public sealed class TestUIExtension : CardUIExtension { public TestUIExtension(ICardFileManager cardFileManager) { this.cardFileManager = cardFileManager; }

private readonly ICardFileManager cardFileManager;

public override async Task Initialized(ICardUIExtensionContext context) { ICardModel cardModel = context.Model;

if (cardModel.Controls.TryGet("Get1CButton", out var control)) { var button = (ButtonViewModel)control; button.CommandClosure.Execute = async p => { string tempPath;

using (TessaSplash.Create(TessaSplashMessage.OpeningFile)) { // загружаем здесь печатный лист согласования для некоторой карточки договора tempPath = await FileExtensionHelper.TryLoadVirtualFile( cardFileManager, cardModel, "file.txt", cardID: new Guid("b6d11bb3-0a6e-4fb3-be59-0f4a01f996b5"), cardTypeID: new Guid("b6d11bb3-0a6e-4fb3-be59-0f4a01f996b5"), fileID: new Guid("b6d11bb3-0a6e-4fb3-be59-0f4a01f996b5"), versionID: new Guid("b6d11bb3-0a6e-4fb3-be59-0f4a01f996b5")); }

if (!string.IsNullOrEmpty(tempPath)) { System.Diagnostics.Process.Start(tempPath); } }; } } }

[Registrator] public sealed class TestUIRegistrator : RegistratorBase { public override void RegisterUnity() { this.UnityContainer .RegisterType<TestUIExtension>(new ContainerControlledLifetimeManager()) ; }

public override void RegisterExtensions(IExtensionContainer extensionContainer) { extensionContainer .RegisterExtension<ICardUIExtension, TestUIExtension>(x => x .WithOrder(ExtensionStage.AfterPlatform, 100) .WithUnity(this.UnityContainer) .WhenCardTypes("Car")) ; } } }

Back to top