From 5c9a7be411e53500fd1fc1c83bf168c3bded0921 Mon Sep 17 00:00:00 2001 From: Alexandru Petre <93531170+alexandru-petre@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:15:18 +0300 Subject: [PATCH] FTP: Fixed viewmodel issues (72176, 72177, 72178) STUD-72176, STUD-72177, STUD-72178 --- Activities/Activities.FTP.sln | 17 +- .../Properties/SharedResources.cs | 7 +- .../FTP/UiPath.FTP.Activities/Localization.cs | 62 ----- .../NetCore/MenuActionBuilder.cs | 3 +- .../NetCore/ViewModels/DeleteViewModel.cs | 30 +- .../ViewModels/DirectoryExistsViewModel.cs | 35 +-- .../ViewModels/DownloadFilesViewModel.cs | 48 +--- .../ViewModels/EnumerateObjectsViewModel.cs | 34 +-- .../NetCore/ViewModels/FileExistsViewModel.cs | 33 +-- .../NetCore/ViewModels/MoveItemViewModel.cs | 48 +--- .../ViewModels/UploadFilesViewModel.cs | 48 +--- .../ViewModels/WithFtpSessionViewModel.cs | 194 ++++++++----- .../UiPath.FTP.Activities.Designer.cs | 42 ++- .../Properties/UiPath.FTP.Activities.resx | 79 +++--- .../Resources/ActivitiesMetadata.json | 259 ++++-------------- .../UiPath.FTP.Activities.csproj | 6 +- .../UiPath.FTP.Activities/WithFtpSession.cs | 14 +- Activities/FTP/UiPath.FTP/FtpSslProtocols.cs | 5 +- Activities/FTP/UiPath.FTP/SftpSession.cs | 14 +- .../ActivitiesConstraints.cs | 4 +- .../ContinuableAsyncNativeActivity.cs | 2 +- .../EnumExtensions.cs | 20 ++ .../InArgumentExtensions.cs | 2 +- .../PathExtensions.cs | 4 +- .../UiPath.Shared.Activities.projitems | 1 + .../Shared/UiPath.Shared/LocalizedEnum.cs | 4 +- .../Shared/UiPath.Shared/SystemExtensions.cs | 22 +- 27 files changed, 365 insertions(+), 672 deletions(-) create mode 100644 Activities/Shared/UiPath.Shared.Activities/EnumExtensions.cs diff --git a/Activities/Activities.FTP.sln b/Activities/Activities.FTP.sln index 3bb4e6a3a..b91e2dfb4 100644 --- a/Activities/Activities.FTP.sln +++ b/Activities/Activities.FTP.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30621.155 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35327.3 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UiPath.FTP", "FTP\UiPath.FTP\UiPath.FTP.csproj", "{E9137637-B657-4C22-85A5-2E30ADF82566}" EndProject @@ -19,10 +19,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution FTP\FTP.build.props = FTP\FTP.build.props EndProjectSection EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "UiPath.Shared.Activities", "Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.shproj", "{4E20C041-2F59-408E-ADB3-0BCFAB48DE61}" +EndProject +Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "UiPath.Shared", "Shared\UiPath.Shared\UiPath.Shared.shproj", "{2E040804-8ED9-4FB8-BB8A-4A38479E2A9E}" +EndProject Global - GlobalSection(SharedMSBuildProjectFiles) = preSolution - Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{fdfc92ee-090c-4e23-9422-f90eb94c43dd}*SharedItemsImports = 5 - EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU @@ -55,4 +56,10 @@ Global GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5AC55779-EA32-41AD-BAAD-1808F8A412CB} EndGlobalSection + GlobalSection(SharedMSBuildProjectFiles) = preSolution + Shared\UiPath.Shared\UiPath.Shared.projitems*{2e040804-8ed9-4fb8-bb8a-4a38479e2a9e}*SharedItemsImports = 13 + Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{4e20c041-2f59-408e-adb3-0bcfab48de61}*SharedItemsImports = 13 + Shared\UiPath.Shared.Activities\UiPath.Shared.Activities.projitems*{fdfc92ee-090c-4e23-9422-f90eb94c43dd}*SharedItemsImports = 5 + Shared\UiPath.Shared\UiPath.Shared.projitems*{fdfc92ee-090c-4e23-9422-f90eb94c43dd}*SharedItemsImports = 5 + EndGlobalSection EndGlobal diff --git a/Activities/FTP/UiPath.FTP.Activities.Design/Properties/SharedResources.cs b/Activities/FTP/UiPath.FTP.Activities.Design/Properties/SharedResources.cs index 4130b77ac..b8e224e5e 100644 --- a/Activities/FTP/UiPath.FTP.Activities.Design/Properties/SharedResources.cs +++ b/Activities/FTP/UiPath.FTP.Activities.Design/Properties/SharedResources.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using UiPath.FTP.Activities.Properties; +using UiPath.FTP.Activities.Properties; namespace UiPath.FTP.Activities.Design.Properties { diff --git a/Activities/FTP/UiPath.FTP.Activities/Localization.cs b/Activities/FTP/UiPath.FTP.Activities/Localization.cs index 001821fb6..df4541309 100644 --- a/Activities/FTP/UiPath.FTP.Activities/Localization.cs +++ b/Activities/FTP/UiPath.FTP.Activities/Localization.cs @@ -54,66 +54,4 @@ public override string Description } } } - - public class LocalizedEnum - { - public string Name { get; private set; } - public Enum Value { get; private set; } - - protected internal LocalizedEnum(string name, Enum value) - { - if (string.IsNullOrWhiteSpace(name)) - { - throw new ArgumentNullException(nameof(name)); - } - if (value == null) - { - throw new ArgumentNullException(nameof(value)); - } - - Name = name; - Value = value; - } - - /// - /// Method that returns a localized enum with the description as a name, if the description exists. - /// - /// - /// - /// - public static LocalizedEnum GetLocalizedValue(Type enumType, object value) - { - var name = enumType.GetEnumName(value); - var field = enumType.GetField(name); - DescriptionAttribute descriptionAttribute = field?.GetCustomAttribute(); - - return new LocalizedEnum(descriptionAttribute?.Description ?? name, value as Enum); - } - } - - public class LocalizedEnum : LocalizedEnum - { - protected LocalizedEnum(string name, Enum value) : base(name, value) - { - } - - public static List GetLocalizedValues() - { - List localizedValues = new List(); - - Type enumType = typeof(T); - Array enumValues = Enum.GetValues(enumType); - - foreach (Enum value in enumValues) - { - string name = enumType.GetEnumName(value); - FieldInfo field = enumType.GetField(name); - DescriptionAttribute descriptionAttribute = field?.GetCustomAttribute(); - - localizedValues.Add(new LocalizedEnum(descriptionAttribute?.Description ?? name, value)); - } - - return localizedValues; - } - } } diff --git a/Activities/FTP/UiPath.FTP.Activities/NetCore/MenuActionBuilder.cs b/Activities/FTP/UiPath.FTP.Activities/NetCore/MenuActionBuilder.cs index fdbfabbf5..312530dd1 100644 --- a/Activities/FTP/UiPath.FTP.Activities/NetCore/MenuActionBuilder.cs +++ b/Activities/FTP/UiPath.FTP.Activities/NetCore/MenuActionBuilder.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using UiPath.Shared; //NOTE: This class was taken from Activities repo namespace UiPath.FTP.Activities.NetCore @@ -90,7 +91,7 @@ public void BuildAndInsertMenuActions() }; foreach (var propertyInfo in _properties.Where(pi => pi != targetPropertyInfo)) { - + propertyInfo.Property.AddMenuAction(menuAction); } diff --git a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DeleteViewModel.cs b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DeleteViewModel.cs index 18f071bf4..3d9d030fd 100644 --- a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DeleteViewModel.cs +++ b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DeleteViewModel.cs @@ -1,18 +1,6 @@ using System.Activities.DesignViewModels; using System.Activities.ViewModels; -using System.Threading.Tasks; -using UiPath.FTP.Activities.NetCore.ViewModels; - -namespace UiPath.FTP.Activities -{ - /// - /// Removes a specified file from an FTP server. - /// - [ViewModelClass(typeof(DeleteViewModel))] - public partial class Delete - { - } -} +using UiPath.FTP.Activities.Properties; namespace UiPath.FTP.Activities.NetCore.ViewModels { @@ -29,24 +17,12 @@ public DeleteViewModel(IDesignServices services) : base(services) /// /// The path of the file that is to be removed from the FTP server. /// - public DesignInArgument RemotePath { get; set; } = new DesignInArgument(); + public DesignInArgument RemotePath { get; set; } protected override void InitializeModel() { base.InitializeModel(); - - RemotePath.IsPrincipal = true; - RemotePath.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - } - - protected override async ValueTask InitializeModelAsync() - { - await base.InitializeModelAsync(); - } - - protected override void InitializeRules() - { - base.InitializeRules(); + PersistValuesChangedDuringInit(); } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DirectoryExistsViewModel.cs b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DirectoryExistsViewModel.cs index 9cefef70f..fe07cc36a 100644 --- a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DirectoryExistsViewModel.cs +++ b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DirectoryExistsViewModel.cs @@ -1,18 +1,5 @@ using System.Activities.DesignViewModels; using System.Activities.ViewModels; -using System.Threading.Tasks; -using UiPath.FTP.Activities.NetCore.ViewModels; - -namespace UiPath.FTP.Activities -{ - /// - /// Checks whether a certain directory exists on an FTP server. - /// - [ViewModelClass(typeof(DirectoryExistsViewModel))] - public partial class DirectoryExists - { - } -} namespace UiPath.FTP.Activities.NetCore.ViewModels { @@ -29,34 +16,22 @@ public DirectoryExistsViewModel(IDesignServices services) : base(services) /// /// The path of the FTP directory in which to check whether the indicated directory exists. /// - public DesignInArgument RemotePath { get; set; } = new DesignInArgument(); + public DesignInArgument RemotePath { get; set; } /// /// A boolean variable that states whether the indicated directory was found or not. /// - public DesignOutArgument Exists { get; set; } = new DesignOutArgument(); + public DesignOutArgument Exists { get; set; } protected override void InitializeModel() { base.InitializeModel(); + PersistValuesChangedDuringInit(); + int propertyOrderIndex = 1; - RemotePath.IsPrincipal = true; RemotePath.OrderIndex = propertyOrderIndex++; - RemotePath.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - - Exists.IsPrincipal = false; - Exists.OrderIndex = propertyOrderIndex++; - } - - protected override async ValueTask InitializeModelAsync() - { - await base.InitializeModelAsync(); - } - - protected override void InitializeRules() - { - base.InitializeRules(); + Exists.OrderIndex = propertyOrderIndex; } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DownloadFilesViewModel.cs b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DownloadFilesViewModel.cs index 139f916d2..78e5c54d3 100644 --- a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DownloadFilesViewModel.cs +++ b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/DownloadFilesViewModel.cs @@ -1,18 +1,5 @@ using System.Activities.DesignViewModels; using System.Activities.ViewModels; -using System.Threading.Tasks; -using UiPath.FTP.Activities.NetCore.ViewModels; - -namespace UiPath.FTP.Activities -{ - /// - /// Downloads the specified files from an FTP server to the specified local folder. - /// - [ViewModelClass(typeof(DownloadFilesViewModel))] - public partial class DownloadFiles - { - } -} namespace UiPath.FTP.Activities.NetCore.ViewModels { @@ -29,59 +16,40 @@ public DownloadFilesViewModel(IDesignServices services) : base(services) /// /// The path of the files on the FTP server that are to be downloaded. /// - public DesignInArgument RemotePath { get; set; } = new DesignInArgument(); + public DesignInArgument RemotePath { get; set; } /// /// The local path for the files that are to be downloaded. /// - public DesignInArgument LocalPath { get; set; } = new DesignInArgument(); + public DesignInArgument LocalPath { get; set; } /// /// If this box is checked, the folders will be downloaded with their respective subfolders. /// - public DesignProperty Recursive { get; set; } = new DesignProperty(); + public DesignProperty Recursive { get; set; } /// /// If this box is checked, the folder path will be created locally in case it does not already exist. /// - public DesignProperty Create { get; set; } = new DesignProperty(); + public DesignProperty Create { get; set; } /// /// If this box is checked, the files will be overwritten locally if they're already stored there. /// - public DesignProperty Overwrite { get; set; } = new DesignProperty(); + public DesignProperty Overwrite { get; set; } protected override void InitializeModel() { base.InitializeModel(); + PersistValuesChangedDuringInit(); + int propertyOrderIndex = 1; - RemotePath.IsPrincipal = true; RemotePath.OrderIndex = propertyOrderIndex++; - RemotePath.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - - LocalPath.IsPrincipal = true; LocalPath.OrderIndex = propertyOrderIndex++; - LocalPath.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - Create.OrderIndex = propertyOrderIndex++; - Create.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; - Recursive.OrderIndex = propertyOrderIndex++; - Recursive.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; - - Overwrite.OrderIndex = propertyOrderIndex++; - Overwrite.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; - } - - protected override async ValueTask InitializeModelAsync() - { - await base.InitializeModelAsync(); - } - - protected override void InitializeRules() - { - base.InitializeRules(); + Overwrite.OrderIndex = propertyOrderIndex; } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/EnumerateObjectsViewModel.cs b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/EnumerateObjectsViewModel.cs index 4aba3d954..50917a716 100644 --- a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/EnumerateObjectsViewModel.cs +++ b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/EnumerateObjectsViewModel.cs @@ -3,16 +3,6 @@ using System.Threading.Tasks; using UiPath.FTP.Activities.NetCore.ViewModels; -namespace UiPath.FTP.Activities -{ - /// - /// Generates a DataTable variable that contains a list comprising the files found at the specified FTP server path. - /// - [ViewModelClass(typeof(EnumerateObjectsViewModel))] - public partial class EnumerateObjects - { - } -} namespace UiPath.FTP.Activities.NetCore.ViewModels { @@ -29,42 +19,30 @@ public EnumerateObjectsViewModel(IDesignServices services) : base(services) /// /// The path of the directory on the FTP server whose files are to be enumerated. /// - public DesignInArgument RemotePath { get; set; } = new DesignInArgument(); + public DesignInArgument RemotePath { get; set; } /// /// If this check box is selected, the subfolders are also included in the enumeration of the files on the FTP server. /// - public DesignProperty Recursive { get; set; } = new DesignProperty(); + public DesignProperty Recursive { get; set; } /// /// A collection of files that have been found on the FTP server. /// - public DesignOutArgument> Files { get; set; } = new DesignOutArgument>(); + public DesignOutArgument> Files { get; set; } protected override void InitializeModel() { base.InitializeModel(); + PersistValuesChangedDuringInit(); + int propertyOrderIndex = 1; - RemotePath.IsPrincipal = true; RemotePath.OrderIndex = propertyOrderIndex++; - RemotePath.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - Files.OrderIndex = propertyOrderIndex++; - Files.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; + Recursive.OrderIndex = propertyOrderIndex; - Recursive.OrderIndex = propertyOrderIndex++; Recursive.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; } - - protected override async ValueTask InitializeModelAsync() - { - await base.InitializeModelAsync(); - } - - protected override void InitializeRules() - { - base.InitializeRules(); - } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/FileExistsViewModel.cs b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/FileExistsViewModel.cs index 8d28edad4..4fe336f63 100644 --- a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/FileExistsViewModel.cs +++ b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/FileExistsViewModel.cs @@ -1,18 +1,5 @@ using System.Activities.DesignViewModels; using System.Activities.ViewModels; -using System.Threading.Tasks; -using UiPath.FTP.Activities.NetCore.ViewModels; - -namespace UiPath.FTP.Activities -{ - /// - /// Checks whether a certain file exists in the specified FTP directory. - /// - [ViewModelClass(typeof(FileExistsViewModel))] - public partial class FileExists - { - } -} namespace UiPath.FTP.Activities.NetCore.ViewModels { @@ -29,34 +16,24 @@ public FileExistsViewModel(IDesignServices services) : base(services) /// /// A boolean variable that states whether the indicated file was found or not. /// - public DesignInArgument RemotePath { get; set; } = new DesignInArgument(); + public DesignInArgument RemotePath { get; set; } /// /// The path of the FTP directory in which to check whether the indicated file exists. /// - public DesignOutArgument Exists { get; set; } = new DesignOutArgument(); + public DesignOutArgument Exists { get; set; } protected override void InitializeModel() { base.InitializeModel(); + PersistValuesChangedDuringInit(); + int propertyOrderIndex = 1; RemotePath.IsPrincipal = true; RemotePath.OrderIndex = propertyOrderIndex++; - RemotePath.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - Exists.OrderIndex = propertyOrderIndex++; - Exists.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - } - - protected override async ValueTask InitializeModelAsync() - { - await base.InitializeModelAsync(); - } - - protected override void InitializeRules() - { - base.InitializeRules(); + Exists.OrderIndex = propertyOrderIndex; } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/MoveItemViewModel.cs b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/MoveItemViewModel.cs index 5a003e649..390515b0a 100644 --- a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/MoveItemViewModel.cs +++ b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/MoveItemViewModel.cs @@ -1,21 +1,5 @@ using System.Activities.DesignViewModels; using System.Activities.ViewModels; -using System.Threading.Tasks; -using UiPath.FTP.Activities.NetCore.ViewModels; - -namespace UiPath.FTP.Activities -{ - namespace UiPath.FTP.Activities - { - /// - /// Moves an item on an FTP server to a different remote path. - /// - [ViewModelClass(typeof(MoveItemViewModel))] - public partial class MoveItem - { - } - } -} namespace UiPath.FTP.Activities.NetCore.ViewModels { @@ -32,51 +16,37 @@ public MoveItemViewModel(IDesignServices services) : base(services) /// /// The remote path on the FTP server where the file is currently located. /// - public DesignInArgument RemotePath { get; set; } = new DesignInArgument(); + public DesignInArgument RemotePath { get; set; } /// /// The remote path on the FTP server where the file will be moved. /// - public DesignInArgument NewPath { get; set; } = new DesignInArgument(); + public DesignInArgument NewPath { get; set; } /// /// If this box is checked, the files will be overwritten in the new remote directory if they're already stored there. /// - public DesignProperty Overwrite { get; set; } = new DesignProperty(); + public DesignProperty Overwrite { get; set; } /// /// Specifies if the automation should continue even when the activity throws an error. /// - public DesignInArgument ContinueOnError { get; set; } = new DesignInArgument(); + public DesignInArgument ContinueOnError { get; set; } protected override void InitializeModel() { base.InitializeModel(); + PersistValuesChangedDuringInit(); + int propertyOrderIndex = 1; - RemotePath.IsPrincipal = true; RemotePath.OrderIndex = propertyOrderIndex++; - RemotePath.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - - NewPath.IsPrincipal = true; NewPath.OrderIndex = propertyOrderIndex++; - NewPath.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - Overwrite.OrderIndex = propertyOrderIndex++; - Overwrite.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; - - ContinueOnError.OrderIndex = propertyOrderIndex++; - ContinueOnError.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; - } + ContinueOnError.OrderIndex = propertyOrderIndex; - protected override async ValueTask InitializeModelAsync() - { - await base.InitializeModelAsync(); - } - - protected override void InitializeRules() - { - base.InitializeRules(); + Overwrite.Widget = new DefaultWidget { Type = ViewModelWidgetType.NullableBoolean }; + ContinueOnError.Widget = new DefaultWidget { Type = ViewModelWidgetType.NullableBoolean }; } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/UploadFilesViewModel.cs b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/UploadFilesViewModel.cs index ebbddb8dd..d0862ef08 100644 --- a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/UploadFilesViewModel.cs +++ b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/UploadFilesViewModel.cs @@ -1,18 +1,5 @@ using System.Activities.DesignViewModels; using System.Activities.ViewModels; -using System.Threading.Tasks; -using UiPath.FTP.Activities.NetCore.ViewModels; - -namespace UiPath.FTP.Activities -{ - /// - /// Uploads a file to an FTP server. - /// - [ViewModelClass(typeof(UploadFilesViewModel))] - public partial class UploadFiles - { - } -} namespace UiPath.FTP.Activities.NetCore.ViewModels { @@ -29,59 +16,40 @@ public UploadFilesViewModel(IDesignServices services) : base(services) /// /// The local path of the files that are to be uploaded. /// - public DesignInArgument LocalPath { get; set; } = new DesignInArgument(); + public DesignInArgument LocalPath { get; set; } /// /// The path on the FTP server where the file is to be uploaded. /// - public DesignInArgument RemotePath { get; set; } = new DesignInArgument(); + public DesignInArgument RemotePath { get; set; } /// /// If this box is checked, the folders will be uploaded with their respective subfolders. /// - public DesignProperty Recursive { get; set; } = new DesignProperty(); + public DesignProperty Recursive { get; set; } /// /// If this box is checked, the folder path will be created on the FTP server in case it does not already exist. /// - public DesignProperty Create { get; set; } = new DesignProperty(); + public DesignProperty Create { get; set; } /// /// If this box is checked, the files will be overwritten on the FTP server if they're already stored there. /// - public DesignProperty Overwrite { get; set; } = new DesignProperty(); + public DesignProperty Overwrite { get; set; } protected override void InitializeModel() { base.InitializeModel(); + PersistValuesChangedDuringInit(); + int propertyOrderIndex = 1; - RemotePath.IsPrincipal = true; RemotePath.OrderIndex = propertyOrderIndex++; - RemotePath.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - - LocalPath.IsPrincipal = true; LocalPath.OrderIndex = propertyOrderIndex++; - LocalPath.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - Create.OrderIndex = propertyOrderIndex++; - Create.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; - Recursive.OrderIndex = propertyOrderIndex++; - Recursive.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; - - Overwrite.OrderIndex = propertyOrderIndex++; - Overwrite.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; - } - - protected override async ValueTask InitializeModelAsync() - { - await base.InitializeModelAsync(); - } - - protected override void InitializeRules() - { - base.InitializeRules(); + Overwrite.OrderIndex = propertyOrderIndex; } } } diff --git a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/WithFtpSessionViewModel.cs b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/WithFtpSessionViewModel.cs index 744d4befb..34521f5b4 100644 --- a/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/WithFtpSessionViewModel.cs +++ b/Activities/FTP/UiPath.FTP.Activities/NetCore/ViewModels/WithFtpSessionViewModel.cs @@ -1,21 +1,12 @@ -using System.Activities.DesignViewModels; +using System; +using System.Activities.DesignViewModels; using System.Activities.ViewModels; -using System.Threading.Tasks; -using UiPath.FTP.Activities.NetCore.ViewModels; +using System.Collections.Generic; +using System.Linq; using System.Security; -using System; +using UiPath.FTP.Activities.Properties; using UiPath.FTP.Enums; - -namespace UiPath.FTP.Activities -{ - /// - /// A container which handles the connection to the FTP server and provides a scope for all the FTP activities. - /// - [ViewModelClass(typeof(WithFtpSessionViewModel))] - public partial class WithFtpSession - { - } -} +using UiPath.Shared; namespace UiPath.FTP.Activities.NetCore.ViewModels { @@ -27,142 +18,119 @@ public partial class WithFtpSessionViewModel : DesignPropertiesViewModel /// public WithFtpSessionViewModel(IDesignServices services) : base(services) { + InitializeFtpsModeDataSource(); } /// /// The URL of the FTP server that you want to connect to. /// - public DesignInArgument Host { get; set; } = new DesignInArgument(); + public DesignInArgument Host { get; set; } /// /// The port of the FTP server that you want to connect to. /// - public DesignInArgument Port { get; set; } = new DesignInArgument(); + public DesignInArgument Port { get; set; } /// /// The username that will be used to connect to the FTP server. /// - public DesignInArgument Username { get; set; } = new DesignInArgument(); + public DesignInArgument Username { get; set; } /// /// The password that will be used to connect to the FTP server. /// - public DesignInArgument Password { get; set; } = new DesignInArgument(); + public DesignInArgument Password { get; set; } /// /// The secure password that will be used to connect to the FTP server. /// - public DesignInArgument SecurePassword { get; set; } = new DesignInArgument(); + public DesignInArgument SecurePassword { get; set; } /// - /// Switches Password as string or secure string + /// Switches Password as string or secure string /// - public DesignProperty PasswordInputModeSwitch { get; set; } = new DesignProperty(); + public DesignProperty PasswordInputModeSwitch { get; set; } /// /// When this box is checked, the username and password fields are ignored, and a standard anonymous user is used instead. /// - public DesignProperty UseAnonymousLogin { get; set; } = new DesignProperty(); + public DesignProperty UseAnonymousLogin { get; set; } /// - /// Switches to the FTPS protocol. + /// Switches to the FTPS protocol. /// - public DesignProperty FtpsMode { get; set; } = new DesignProperty(); + public DesignProperty FtpsMode { get; set; } /// /// Select the SSL protocol to be used for the FTPS connection /// - public DesignProperty SslProtocols { get; set; } = new DesignProperty(); + public DesignProperty SslProtocols { get; set; } /// /// Check this box if you want to use the SFTP transfer protocol. /// - public DesignProperty UseSftp { get; set; } = new DesignProperty(); + public DesignProperty UseSftp { get; set; } /// /// The path to the certificate used to verify the identity of the client. /// - public DesignInArgument ClientCertificatePath { get; set; } = new DesignInArgument(); + public DesignInArgument ClientCertificatePath { get; set; } /// /// The password for the client certificate. /// - public DesignInArgument ClientCertificatePassword { get; set; } = new DesignInArgument(); + public DesignInArgument ClientCertificatePassword { get; set; } /// /// The secure password that will be used to connect to the FTP server. /// - public DesignInArgument ClientCertificateSecurePassword { get; set; } = new DesignInArgument(); + public DesignInArgument ClientCertificateSecurePassword { get; set; } /// - /// Switches Password as string or secure string + /// Switches Password as string or secure string /// - public DesignProperty CertificatePasswordInputModeSwitch { get; set; } = new DesignProperty(); + public DesignProperty CertificatePasswordInputModeSwitch { get; set; } /// /// If this box is checked, all certificates will be accepted, including the ones that are expired or not verified. /// - public DesignProperty AcceptAllCertificates { get; set; } = new DesignProperty(); + public DesignProperty AcceptAllCertificates { get; set; } /// /// Specifies if the automation should continue even when the activity throws an error. /// - public DesignInArgument ContinueOnError { get; set; } = new DesignInArgument(); + public DesignInArgument ContinueOnError { get; set; } + + private static DataSource _sslProtocolsDataSource; protected override void InitializeModel() { base.InitializeModel(); + PersistValuesChangedDuringInit(); + int propertyOrderIndex = 1; Host.OrderIndex = propertyOrderIndex++; - Host.IsPrincipal = true; - Username.OrderIndex = propertyOrderIndex++; - Username.IsPrincipal = true; - Password.OrderIndex = propertyOrderIndex++; - Password.IsVisible = true; - Password.IsPrincipal = true; - SecurePassword.OrderIndex = propertyOrderIndex++; - SecurePassword.IsVisible = false; - SecurePassword.IsPrincipal = true; - - PasswordInputModeSwitch.IsVisible = false; - Port.OrderIndex = propertyOrderIndex++; - Port.Widget = new DefaultWidget { Type = ViewModelWidgetType.Input }; - UseAnonymousLogin.OrderIndex = propertyOrderIndex++; - UseAnonymousLogin.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; - ContinueOnError.OrderIndex = propertyOrderIndex++; - ContinueOnError.Widget = new DefaultWidget { Type = ViewModelWidgetType.NullableBoolean }; - AcceptAllCertificates.OrderIndex = propertyOrderIndex++; - AcceptAllCertificates.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; - ClientCertificatePath.OrderIndex = propertyOrderIndex++; - ClientCertificatePassword.OrderIndex = propertyOrderIndex++; - ClientCertificatePassword.IsPrincipal = false; - ClientCertificatePassword.IsVisible = true; - ClientCertificateSecurePassword.OrderIndex = propertyOrderIndex++; - ClientCertificateSecurePassword.IsPrincipal = false; - ClientCertificateSecurePassword.IsVisible = false; - - CertificatePasswordInputModeSwitch.IsVisible = false; - FtpsMode.OrderIndex = propertyOrderIndex++; - FtpsMode.Widget = new DefaultWidget { Type = ViewModelWidgetType.Dropdown }; - SslProtocols.OrderIndex = propertyOrderIndex++; - SslProtocols.Widget = new DefaultWidget { Type = ViewModelWidgetType.MultiSelect }; + UseSftp.OrderIndex = propertyOrderIndex; - UseSftp.OrderIndex = propertyOrderIndex++; + ContinueOnError.Widget = new DefaultWidget { Type = ViewModelWidgetType.NullableBoolean }; + SslProtocols.Widget = new DefaultWidget { Type = ViewModelWidgetType.MultiSelect }; UseSftp.Widget = new DefaultWidget { Type = ViewModelWidgetType.Toggle }; + SslProtocols.DataSource = _sslProtocolsDataSource; + MenuActionsBuilder.WithValueProperty(PasswordInputModeSwitch) .AddMenuProperty(Password, PasswordInputMode.Password) .AddMenuProperty(SecurePassword, PasswordInputMode.SecurePassword) @@ -174,17 +142,13 @@ protected override void InitializeModel() .BuildAndInsertMenuActions(); } - protected override async ValueTask InitializeModelAsync() - { - await base.InitializeModelAsync(); - } - /// protected override void InitializeRules() { base.InitializeRules(); Rule(nameof(PasswordInputModeSwitch), PasswordInputModeChanged_Action); Rule(nameof(CertificatePasswordInputModeSwitch), CertificatePasswordInputModeChanged_Action); + Rule(nameof(FtpsMode), FtpEncryptionModeChanged_Action); } /// @@ -193,6 +157,7 @@ protected override void ManualRegisterDependencies() base.ManualRegisterDependencies(); RegisterDependency(PasswordInputModeSwitch, nameof(PasswordInputModeSwitch.Value), nameof(PasswordInputModeSwitch)); RegisterDependency(CertificatePasswordInputModeSwitch, nameof(CertificatePasswordInputModeSwitch.Value), nameof(CertificatePasswordInputModeSwitch)); + RegisterDependency(FtpsMode, nameof(FtpsMode.Value), nameof(FtpsMode)); } /// @@ -234,5 +199,90 @@ private void CertificatePasswordInputModeChanged_Action() throw new NotImplementedException(); } } + + private void FtpEncryptionModeChanged_Action() + { + if (FtpsMode.Value == FTP.FtpsMode.None) + { + SslProtocols.IsVisible = false; + return; + } + + SslProtocols.IsVisible = true; + } + + private static void InitializeFtpsModeDataSource() + { + if (_sslProtocolsDataSource is not null) + { + return; + } + + var protocols = Enum.GetValues() + .Where(s => s != FtpSslProtocols.Auto && s != FtpSslProtocols.Default) + .OrderBy(s => s) + .Reverse() // newer, non-obsolete protocols first + .ToList(); + protocols.Add(FtpSslProtocols.Default); // add Default as the last option, by default it would have been between Tls and Tls11 + + _sslProtocolsDataSource = DataSourceBuilder + .WithId(s => Enum.GetName(s)) + .WithLabel(s => GetFtpSslProtocolLabel(s)) + .WithMultipleSelection( + selectionToValue: s => + { + if (s.Count == 0) + { + return FtpSslProtocols.Auto; + } + + return s.Aggregate((a, b) => a | b); + }, + valueToSelection: s => + { + // try first to match a single value that covers multiple flags (ahem, Default) + foreach (var value in Enum.GetValues()) + { + if (value == FtpSslProtocols.Auto) // FtpSslProtocols.Auto is not displayed + { + continue; + } + if (value == s) + { + return new List() { s }; + } + } + + List list = new List(); + // if no single value matches, decompose it into the flags it contains + foreach (var value in Enum.GetValues()) + { + if (s.HasFlag(value)) + { + list.Add(value); + } + } + return list; + } + ) + .WithData(protocols) + .Build(); + } + + // gets the value of a localized enum and appends Obsolete if necessary + private static string GetFtpSslProtocolLabel(FtpSslProtocols value) + { + var localizedName = LocalizedEnum.GetLocalizedValue(typeof(FtpSslProtocols), value).Name; + + // get the attributes of the enum value + var field = typeof(FtpSslProtocols).GetField(value.ToString()); + if (field.GetCustomAttributesData().Any(a => a.AttributeType == typeof(ObsoleteAttribute))) + { + return string.Format(Resources.ObsoleteEnumValue, localizedName); + } + + return localizedName; + } + } } diff --git a/Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.Designer.cs b/Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.Designer.cs index fa0829be2..ca805bb91 100644 --- a/Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.Designer.cs +++ b/Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.Designer.cs @@ -29,7 +29,7 @@ public class UiPath_FTP_Activities { private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] - public UiPath_FTP_Activities() { + internal UiPath_FTP_Activities() { } /// @@ -79,7 +79,7 @@ public static string Activity_Delete_Description { } /// - /// Looks up a localized string similar to Delete file or folder. + /// Looks up a localized string similar to Delete File or Folder. /// public static string Activity_Delete_Name { get { @@ -169,7 +169,7 @@ public static string Activity_DownloadFiles_Description { } /// - /// Looks up a localized string similar to Download files. + /// Looks up a localized string similar to Download Files. /// public static string Activity_DownloadFiles_Name { get { @@ -403,7 +403,7 @@ public static string Activity_MoveItem_Description { } /// - /// Looks up a localized string similar to Move file or folder. + /// Looks up a localized string similar to Move File or Folder. /// public static string Activity_MoveItem_Name { get { @@ -601,7 +601,7 @@ public static string Activity_WithFtpSession_Description { } /// - /// Looks up a localized string similar to Use FTP connection. + /// Looks up a localized string similar to Use FTP Connection. /// public static string Activity_WithFtpSession_Name { get { @@ -635,9 +635,9 @@ public static string Activity_WithFtpSession_Property_CertificatePasswordInputMo return ResourceManager.GetString("Activity_WithFtpSession_Property_CertificatePasswordInputModeSwitch_Description", resourceCulture); } } - + /// - /// Looks up a localized string similar to CertificatePasswordInputModeSwitch. + /// Looks up a localized string similar to SecurePasswordInputModeSwitch. /// public static string Activity_WithFtpSession_Property_CertificatePasswordInputModeSwitch_Name { get { @@ -942,6 +942,15 @@ public static string Activity_WithFtpSession_Property_SslProtocols_Name { } } + /// + /// Looks up a localized string similar to Leave empty for auto configuration. + /// + public static string Activity_WithFtpSession_Property_SslProtocols_Placeholder { + get { + return ResourceManager.GetString("Activity_WithFtpSession_Property_SslProtocols_Placeholder", resourceCulture); + } + } + /// /// Looks up a localized string similar to When this box is checked, the username and password fields are ignored, and a standard anonymous user is used instead.. /// @@ -1069,7 +1078,7 @@ public static string ClientCertificatePassword { } /// - /// Looks up a localized string similar to ClientCertificatePassword. + /// Looks up a localized string similar to Client certificate password. /// public static string ClientCertificatePasswordDescription { get { @@ -1105,7 +1114,7 @@ public static string Common { } /// - /// Looks up a localized string similar to ContinueOnError. + /// Looks up a localized string similar to Continue on error. /// public static string ContinueOnError { get { @@ -1339,7 +1348,7 @@ public static string LocalPath { } /// - /// Looks up a localized string similar to LocalPath. + /// Looks up a localized string similar to Local path. /// public static string LocalPathDescription { get { @@ -1375,7 +1384,7 @@ public static string NewPath { } /// - /// Looks up a localized string similar to NewPath. + /// Looks up a localized string similar to New path. /// public static string NewPathDescription { get { @@ -1392,6 +1401,15 @@ public static string NoValidAuthenticationMethod { } } + /// + /// Looks up a localized string similar to {0} (Obsolete). + /// + public static string ObsoleteEnumValue { + get { + return ResourceManager.GetString("ObsoleteEnumValue", resourceCulture); + } + } + /// /// Looks up a localized string similar to An FTP session was already provided for the current context.. /// @@ -1501,7 +1519,7 @@ public static string RemotePath { } /// - /// Looks up a localized string similar to Remote Path. + /// Looks up a localized string similar to Remote path. /// public static string RemotePathDescription { get { diff --git a/Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.resx b/Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.resx index 037f0f994..70923b296 100644 --- a/Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.resx +++ b/Activities/FTP/UiPath.FTP.Activities/Properties/UiPath.FTP.Activities.resx @@ -1,17 +1,17 @@  - @@ -279,10 +279,10 @@ Activity name - ClientCertificatePassword + Client certificate password - ContinueOnError + Continue on error Files @@ -291,10 +291,10 @@ Host - LocalPath + Local path - NewPath + New path Password @@ -303,7 +303,7 @@ Port - Remote Path + Remote path When this box is checked, the username and password fields are ignored, and a standard anonymous user is used instead. @@ -325,7 +325,7 @@ Activity description - Delete file or folder + Delete File or Folder Activity name @@ -469,7 +469,7 @@ Activity description - Use FTP connection + Use FTP Connection Activity name @@ -573,7 +573,7 @@ Activity description - Download files + Download Files Activity name @@ -621,7 +621,7 @@ Activity description - Move file or folder + Move File or Folder Activity name @@ -753,4 +753,11 @@ You must provide a value for {0}. error message + + {0} (Obsolete) + it is used to mark the obsolete values in a dropdown + + + Leave empty for auto configuration + \ No newline at end of file diff --git a/Activities/FTP/UiPath.FTP.Activities/Resources/ActivitiesMetadata.json b/Activities/FTP/UiPath.FTP.Activities/Resources/ActivitiesMetadata.json index 97b29387e..cdbfcb4ff 100644 --- a/Activities/FTP/UiPath.FTP.Activities/Resources/ActivitiesMetadata.json +++ b/Activities/FTP/UiPath.FTP.Activities/Resources/ActivitiesMetadata.json @@ -2,15 +2,11 @@ "AssemblyRelativePath": "UiPath.FTP.Activities.dll", "Activities": [ { - "AssemblyQualifiedName": null, "FullName": "UiPath.FTP.Activities.Delete", "ShortName": "Delete", "DisplayNameKey": "Activity_Delete_Name", "DescriptionKey": "Activity_Delete_Description", "IconKey": "Delete_file_or_folder.svg", - "CategoryKey": null, - "ActivityColor": null, - "ActivityNameBackgroundColor": null, "Properties": [ { "Name": "RemotePath", @@ -20,26 +16,18 @@ "IsPrincipal": true, "IsVisible": true, "Category": { - "Name": null, - "DisplayNameKey": "Category_Principal_Name" - }, - "Widget": null, - "IconKey": null + "DisplayNameKey": "Input" + } } ], - "DefaultFactory": null, - "ViewModelType": null + "ViewModelType": "UiPath.FTP.Activities.NetCore.ViewModels.DeleteViewModel" }, { - "AssemblyQualifiedName": null, "FullName": "UiPath.FTP.Activities.DirectoryExists", "ShortName": "DirectoryExists", "DisplayNameKey": "Activity_DirectoryExists_Name", "DescriptionKey": "Activity_DirectoryExists_Description", "IconKey": "Folder_exists.svg", - "CategoryKey": null, - "ActivityColor": null, - "ActivityNameBackgroundColor": null, "Properties": [ { "Name": "RemotePath", @@ -49,11 +37,8 @@ "IsPrincipal": true, "IsVisible": true, "Category": { - "Name": null, - "DisplayNameKey": "Category_Principal_Name" - }, - "Widget": null, - "IconKey": null + "DisplayNameKey": "Input" + } }, { "Name": "Exists", @@ -63,26 +48,18 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, - "DisplayNameKey": "Category_Output_Name" - }, - "Widget": null, - "IconKey": null + "DisplayNameKey": "Output" + } } ], - "DefaultFactory": null, - "ViewModelType": null + "ViewModelType": "UiPath.FTP.Activities.NetCore.ViewModels.DirectoryExistsViewModel" }, { - "AssemblyQualifiedName": null, "FullName": "UiPath.FTP.Activities.DownloadFiles", "ShortName": "DownloadFiles", "DisplayNameKey": "Activity_DownloadFiles_Name", "DescriptionKey": "Activity_DownloadFiles_Description", "IconKey": "Download_files.svg", - "CategoryKey": null, - "ActivityColor": null, - "ActivityNameBackgroundColor": null, "Properties": [ { "Name": "RemotePath", @@ -92,11 +69,8 @@ "IsPrincipal": true, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Principal_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "LocalPath", @@ -106,11 +80,8 @@ "IsPrincipal": true, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Principal_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "Recursive", @@ -120,11 +91,8 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Others_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "Create", @@ -134,11 +102,8 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Others_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "Overwrite", @@ -148,26 +113,18 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Others_Name" - }, - "Widget": null, - "IconKey": null + } } ], - "DefaultFactory": null, - "ViewModelType": null + "ViewModelType": "UiPath.FTP.Activities.NetCore.ViewModels.DownloadFilesViewModel" }, { - "AssemblyQualifiedName": null, "FullName": "UiPath.FTP.Activities.EnumerateObjects", "ShortName": "EnumerateObjects", "DisplayNameKey": "Activity_EnumerateObjects_Name", "DescriptionKey": "Activity_EnumerateObjects_Description", "IconKey": "Get_files.svg", - "CategoryKey": null, - "ActivityColor": null, - "ActivityNameBackgroundColor": null, "Properties": [ { "Name": "RemotePath", @@ -177,11 +134,8 @@ "IsPrincipal": true, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Principal_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "Recursive", @@ -191,11 +145,8 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Others_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "Files", @@ -205,26 +156,18 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Output_Name" - }, - "Widget": null, - "IconKey": null + } } ], - "DefaultFactory": null, - "ViewModelType": null + "ViewModelType": "UiPath.FTP.Activities.NetCore.ViewModels.EnumerateObjectsViewModel" }, { - "AssemblyQualifiedName": null, "FullName": "UiPath.FTP.Activities.FileExists", "ShortName": "FileExists", "DisplayNameKey": "Activity_FileExists_Name", "DescriptionKey": "Activity_FileExists_Description", "IconKey": "File_exists.svg", - "CategoryKey": null, - "ActivityColor": null, - "ActivityNameBackgroundColor": null, "Properties": [ { "Name": "RemotePath", @@ -234,11 +177,8 @@ "IsPrincipal": true, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Principal_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "Exists", @@ -248,26 +188,18 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Output_Name" - }, - "Widget": null, - "IconKey": null + } } ], - "DefaultFactory": null, - "ViewModelType": null + "ViewModelType": "UiPath.FTP.Activities.NetCore.ViewModels.FileExistsViewModel" }, { - "AssemblyQualifiedName": null, "FullName": "UiPath.FTP.Activities.MoveItem", "ShortName": "MoveItem", "DisplayNameKey": "Activity_MoveItem_Name", "DescriptionKey": "Activity_MoveItem_Description", "IconKey": "Move_file_or_folder.svg", - "CategoryKey": null, - "ActivityColor": null, - "ActivityNameBackgroundColor": null, "Properties": [ { "Name": "RemotePath", @@ -277,11 +209,8 @@ "IsPrincipal": true, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Principal_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "NewPath", @@ -291,11 +220,8 @@ "IsPrincipal": true, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Principal_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "Overwrite", @@ -305,11 +231,8 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Others_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "ContinueOnError", @@ -319,26 +242,18 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Others_Name" - }, - "Widget": null, - "IconKey": null + } } ], - "DefaultFactory": null, - "ViewModelType": null + "ViewModelType": "UiPath.FTP.Activities.NetCore.ViewModels.MoveItemViewModel" }, { - "AssemblyQualifiedName": null, "FullName": "UiPath.FTP.Activities.UploadFiles", "ShortName": "UploadFiles", "DisplayNameKey": "Activity_UploadFiles_Name", "DescriptionKey": "Activity_UploadFiles_Description", "IconKey": "Upload_files.svg", - "CategoryKey": null, - "ActivityColor": null, - "ActivityNameBackgroundColor": null, "Properties": [ { "Name": "LocalPath", @@ -348,11 +263,8 @@ "IsPrincipal": true, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Principal_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "RemotePath", @@ -362,11 +274,8 @@ "IsPrincipal": true, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Principal_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "Recursive", @@ -376,11 +285,8 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Others_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "Create", @@ -390,11 +296,8 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Others_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "Overwrite", @@ -404,40 +307,22 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Others_Name" - }, - "Widget": null, - "IconKey": null + } } ], - "DefaultFactory": null, - "ViewModelType": null + "ViewModelType": "UiPath.FTP.Activities.NetCore.ViewModels.UploadFilesViewModel" }, { - "AssemblyQualifiedName": null, "FullName": "UiPath.FTP.Activities.WithFtpSession", "ShortName": "WithFtpSession", "DisplayNameKey": "Activity_WithFtpSession_Name", "DescriptionKey": "Activity_WithFtpSession_Description", "IconKey": "FTP_Connection.svg", - "CategoryKey": null, - "ActivityColor": null, - "ActivityNameBackgroundColor": null, "Properties": [ { "Name": "Body", - "DisplayNameKey": null, - "TooltipKey": null, - "IsRequired": false, - "IsPrincipal": false, - "IsVisible": false, - "Category": { - "Name": null, - "DisplayNameKey": null - }, - "Widget": null, - "IconKey": null + "IsVisible": false }, { "Name": "Host", @@ -445,10 +330,7 @@ "TooltipKey": "Activity_WithFtpSession_Property_Host_Description", "IsRequired": true, "IsPrincipal": true, - "IsVisible": true, - "Category": null, - "Widget": null, - "IconKey": null + "IsVisible": true }, { "Name": "Port", @@ -456,10 +338,7 @@ "TooltipKey": "Activity_WithFtpSession_Property_Port_Description", "IsRequired": false, "IsPrincipal": false, - "IsVisible": true, - "Category": null, - "Widget": null, - "IconKey": null + "IsVisible": true }, { "Name": "Username", @@ -467,10 +346,7 @@ "TooltipKey": "Activity_WithFtpSession_Property_Username_Description", "IsRequired": false, "IsPrincipal": true, - "IsVisible": true, - "Category": null, - "Widget": null, - "IconKey": null + "IsVisible": true }, { "Name": "Password", @@ -478,10 +354,7 @@ "TooltipKey": "Activity_WithFtpSession_Property_Password_Description", "IsRequired": false, "IsPrincipal": true, - "IsVisible": true, - "Category": null, - "Widget": null, - "IconKey": null + "IsVisible": true }, { "Name": "SecurePassword", @@ -489,10 +362,7 @@ "TooltipKey": "Activity_WithFtpSession_Property_SecurePassword_Description", "IsRequired": false, "IsPrincipal": true, - "IsVisible": false, - "Category": null, - "Widget": null, - "IconKey": null + "IsVisible": false }, { "Name": "PasswordInputModeSwitch", @@ -501,7 +371,6 @@ "IsRequired": false, "IsVisible": false, "Category": { - "Name": null, "DisplayNameKey": "Input" } }, @@ -511,10 +380,7 @@ "TooltipKey": "Activity_WithFtpSession_Property_UseAnonymousLogin_Description", "IsRequired": false, "IsPrincipal": false, - "IsVisible": true, - "Category": null, - "Widget": null, - "IconKey": null + "IsVisible": true }, { "Name": "FtpsMode", @@ -524,25 +390,20 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Security_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "SslProtocols", "DisplayNameKey": "Activity_WithFtpSession_Property_SslProtocols_Name", "TooltipKey": "Activity_WithFtpSession_Property_SslProtocols_Description", + "placeholderKey": "Activity_WithFtpSession_Property_SslProtocols_Placeholder", "IsRequired": false, "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Security_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "UseSftp", @@ -552,11 +413,8 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Security_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "ClientCertificatePath", @@ -566,11 +424,8 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Security_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "ClientCertificatePassword", @@ -580,11 +435,8 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Security_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "ClientCertificateSecurePassword", @@ -594,11 +446,8 @@ "IsPrincipal": false, "IsVisible": false, "Category": { - "Name": null, "DisplayNameKey": "Category_Security_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "CertificatePasswordInputModeSwitch", @@ -607,7 +456,6 @@ "IsRequired": false, "IsVisible": false, "Category": { - "Name": null, "DisplayNameKey": "Input" } }, @@ -619,11 +467,8 @@ "IsPrincipal": false, "IsVisible": true, "Category": { - "Name": null, "DisplayNameKey": "Category_Security_Name" - }, - "Widget": null, - "IconKey": null + } }, { "Name": "ContinueOnError", @@ -631,19 +476,13 @@ "TooltipKey": "Activity_WithFtpSession_Property_ContinueOnError_Description", "IsRequired": false, "IsPrincipal": false, - "IsVisible": true, - "Category": null, - "Widget": null, - "IconKey": null + "IsVisible": true } ], - "DefaultFactory": null, - "ViewModelType": null + "ViewModelType": "UiPath.FTP.Activities.NetCore.ViewModels.WithFtpSessionViewModel" } ], "DefaultActivityColor": "#526069", "DefaultActivityNameBackgroundColor": "#FFFFFF", - "DefaultActivityIconKey": null, - "AssemblyIconKey": null, "ResourceManagerName": "UiPath.FTP.Activities.Properties.UiPath.FTP.Activities" } \ No newline at end of file diff --git a/Activities/FTP/UiPath.FTP.Activities/UiPath.FTP.Activities.csproj b/Activities/FTP/UiPath.FTP.Activities/UiPath.FTP.Activities.csproj index 87385e588..41362d3fb 100644 --- a/Activities/FTP/UiPath.FTP.Activities/UiPath.FTP.Activities.csproj +++ b/Activities/FTP/UiPath.FTP.Activities/UiPath.FTP.Activities.csproj @@ -52,10 +52,14 @@ + - + + + + \ No newline at end of file diff --git a/Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs b/Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs index b7ec37f30..425188ca0 100644 --- a/Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs +++ b/Activities/FTP/UiPath.FTP.Activities/WithFtpSession.cs @@ -55,7 +55,7 @@ public partial class WithFtpSession : ContinuableAsyncNativeActivity [LocalizedDisplayName(nameof(Resources.Activity_WithFtpSession_Property_PasswordInputModeSwitch_Name))] [LocalizedDescription(nameof(Resources.Activity_WithFtpSession_Property_PasswordInputModeSwitch_Description))] public PasswordInputMode PasswordInputModeSwitch { get; set; } - + [DefaultValue(false)] [LocalizedCategory(nameof(Resources.Credentials))] [LocalizedDisplayName(nameof(Resources.Activity_WithFtpSession_Property_UseAnonymousLogin_Name))] @@ -68,7 +68,7 @@ public partial class WithFtpSession : ContinuableAsyncNativeActivity [LocalizedDescription(nameof(Resources.Activity_WithFtpSession_Property_FtpsMode_Description))] public FtpsMode FtpsMode { get; set; } - [DefaultValue(FtpSslProtocols.Default)] + [DefaultValue(FtpSslProtocols.Auto)] [LocalizedCategory(nameof(Resources.Security))] [LocalizedDisplayName(nameof(Resources.Activity_WithFtpSession_Property_SslProtocols_Name))] [LocalizedDescription(nameof(Resources.Activity_WithFtpSession_Property_SslProtocols_Description))] @@ -100,7 +100,7 @@ public partial class WithFtpSession : ContinuableAsyncNativeActivity [LocalizedDisplayName(nameof(Resources.Activity_WithFtpSession_Property_CertificatePasswordInputModeSwitch_Name))] [LocalizedDescription(nameof(Resources.Activity_WithFtpSession_Property_CertificatePasswordInputModeSwitch_Description))] public PasswordInputMode CertificatePasswordInputModeSwitch { get; set; } - + [DefaultValue(false)] [LocalizedCategory(nameof(Resources.Security))] [LocalizedDisplayName(nameof(Resources.Activity_WithFtpSession_Property_AcceptAllCertificates_Name))] @@ -144,8 +144,6 @@ public partial class WithFtpSession : ContinuableAsyncNativeActivity public WithFtpSession() { - FtpsMode = FtpsMode.None; - SslProtocols = FtpSslProtocols.Default; Body = new ActivityAction() { Argument = new DelegateInArgument(FtpSessionPropertyName), @@ -170,11 +168,11 @@ protected override async Task> ExecuteAsync(Native SecureString securePasswordValue = SecurePassword.Get(context); string clientCertificatePasswordValue = ClientCertificatePassword.Get(context); SecureString clientCertificateSecurePasswordValue = ClientCertificateSecurePassword.Get(context); - + FtpConfiguration ftpConfiguration = new FtpConfiguration(Host.Get(context)); ftpConfiguration.Port = Port.Expression == null ? null : (int?)Port.Get(context); ftpConfiguration.UseAnonymousLogin = UseAnonymousLogin; - ftpConfiguration.SslProtocols = SslProtocols; + ftpConfiguration.SslProtocols = SslProtocols; ftpConfiguration.Password = passwordValue; ftpConfiguration.ProxyType = ProxyType; @@ -206,7 +204,7 @@ protected override async Task> ExecuteAsync(Native { throw new ArgumentNullException(Resources.EmptyUsernameException); } - + if (string.IsNullOrWhiteSpace(ftpConfiguration.Password) && string.IsNullOrWhiteSpace(ftpConfiguration.ClientCertificatePath)) { throw new ArgumentNullException(Resources.NoValidAuthenticationMethod); diff --git a/Activities/FTP/UiPath.FTP/FtpSslProtocols.cs b/Activities/FTP/UiPath.FTP/FtpSslProtocols.cs index fc99725c6..0e114cad6 100644 --- a/Activities/FTP/UiPath.FTP/FtpSslProtocols.cs +++ b/Activities/FTP/UiPath.FTP/FtpSslProtocols.cs @@ -6,9 +6,12 @@ namespace UiPath.FTP [Flags] public enum FtpSslProtocols { - None = SslProtocols.None, + Auto = SslProtocols.None, // see description of SslProtocols.None, it's actually Auto + [Obsolete("Allows only obsolete protocols, use Auto instead")] Default = SslProtocols.Default, + [Obsolete("Weak protocol, should not be used")] TLS_1_0 = SslProtocols.Tls, + [Obsolete("Weak protocol, should not be used")] TLS_1_1 = SslProtocols.Tls11, TLS_1_2 = SslProtocols.Tls12 } diff --git a/Activities/FTP/UiPath.FTP/SftpSession.cs b/Activities/FTP/UiPath.FTP/SftpSession.cs index fc46f0d76..cdb08616c 100644 --- a/Activities/FTP/UiPath.FTP/SftpSession.cs +++ b/Activities/FTP/UiPath.FTP/SftpSession.cs @@ -27,7 +27,7 @@ public SftpSession(FtpConfiguration ftpConfiguration) ConnectionInfo connectionInfo = null; var authMethods = new List(); - + //Add password authentication method if password is provided if (!String.IsNullOrEmpty(ftpConfiguration.Password)) { @@ -113,7 +113,7 @@ private IEnumerable> GetRemoteListing(string remotePath, s string initialWorkingDirectory = _sftpClient.WorkingDirectory; _sftpClient.ChangeDirectory(remotePath); - + List> listing = new List>(); ISftpFile currentDirectory = _sftpClient.Get(_sftpClient.WorkingDirectory); IEnumerable items = _sftpClient.ListDirectory(currentDirectory.FullName); @@ -499,7 +499,7 @@ async Task IFtpSession.DownloadAsync(string remotePath, string localPath, bool o using (Stream fileStream = File.OpenWrite(localPath)) { await Task.Factory.FromAsync(_sftpClient.BeginDownloadFile(remotePath, fileStream), _sftpClient.EndDownloadFile); - } + } } else { @@ -605,9 +605,9 @@ void IFtpSession.Move(string remotePath, string newPath, bool overwrite) { throw new IOException(Resources.FileExistsException); } - + var file = _sftpClient.Get(remotePath); - + if(_sftpClient.Exists(newPath) && file.IsRegularFile) { var movePath = _sftpClient.Get(newPath); @@ -726,7 +726,7 @@ async Task IFtpSession.UploadAsync(string localPath, string remotePath, bool ove using (Stream fileStream = File.OpenRead(localPath)) { await Task.Factory.FromAsync(_sftpClient.BeginUploadFile(fileStream, remotePath, overwrite, null, null), _sftpClient.EndUploadFile); - } + } } else { @@ -763,7 +763,7 @@ protected virtual void Dispose(bool disposing) // } // This code added to correctly implement the disposable pattern. - void IDisposable.Dispose() + void IDisposable.Dispose() { // Do not change this code. Put cleanup code in Dispose(bool disposing) above. Dispose(true); diff --git a/Activities/Shared/UiPath.Shared.Activities/ActivitiesConstraints.cs b/Activities/Shared/UiPath.Shared.Activities/ActivitiesConstraints.cs index 464d1216a..1ea0ecdeb 100644 --- a/Activities/Shared/UiPath.Shared.Activities/ActivitiesConstraints.cs +++ b/Activities/Shared/UiPath.Shared.Activities/ActivitiesConstraints.cs @@ -5,7 +5,7 @@ namespace UiPath.Shared.Activities { - public static class ActivityConstraints + internal static class ActivityConstraints { [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] public static Constraint HasParentType(string validationMessage) where TActivity : Activity where TParent : Activity @@ -14,7 +14,7 @@ public static Constraint HasParentType(string validationMess } [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter")] - public static Constraint HasParent(Func condition, string validationMessage) + public static Constraint HasParent(Func condition, string validationMessage) where TActivity : Activity { var element = new DelegateInArgument(); diff --git a/Activities/Shared/UiPath.Shared.Activities/ContinuableAsyncNativeActivity.cs b/Activities/Shared/UiPath.Shared.Activities/ContinuableAsyncNativeActivity.cs index 630ece274..452e46f3f 100644 --- a/Activities/Shared/UiPath.Shared.Activities/ContinuableAsyncNativeActivity.cs +++ b/Activities/Shared/UiPath.Shared.Activities/ContinuableAsyncNativeActivity.cs @@ -28,7 +28,7 @@ protected override void Execute(NativeActivityContext context) } protected override void BookmarkResumptionCallback(NativeActivityContext context, Bookmark bookmark, object value) - { + { try { base.BookmarkResumptionCallback(context, bookmark, value); diff --git a/Activities/Shared/UiPath.Shared.Activities/EnumExtensions.cs b/Activities/Shared/UiPath.Shared.Activities/EnumExtensions.cs new file mode 100644 index 000000000..d067836ac --- /dev/null +++ b/Activities/Shared/UiPath.Shared.Activities/EnumExtensions.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace UiPath.Shared.Activities +{ + internal static class EnumExtensions where T : struct + { + public static bool EnumTryParseNoIntegers(string value, out T result) + { + if (int.TryParse(value, out _)) + { + result = default; + return false; + } + + return Enum.TryParse(value, out result); + } + } +} diff --git a/Activities/Shared/UiPath.Shared.Activities/InArgumentExtensions.cs b/Activities/Shared/UiPath.Shared.Activities/InArgumentExtensions.cs index 44447aad9..335e63a1f 100644 --- a/Activities/Shared/UiPath.Shared.Activities/InArgumentExtensions.cs +++ b/Activities/Shared/UiPath.Shared.Activities/InArgumentExtensions.cs @@ -14,7 +14,7 @@ namespace UiPath.Shared.Activities /// /// Taken from System Activities /// - public static class InArgumentExtensions + internal static class InArgumentExtensions { public static T? GetArgumentLiteralValue(this InArgument inArgument) where T : struct { diff --git a/Activities/Shared/UiPath.Shared.Activities/PathExtensions.cs b/Activities/Shared/UiPath.Shared.Activities/PathExtensions.cs index 2e130a5a7..e6c3d1a99 100644 --- a/Activities/Shared/UiPath.Shared.Activities/PathExtensions.cs +++ b/Activities/Shared/UiPath.Shared.Activities/PathExtensions.cs @@ -8,7 +8,7 @@ namespace UiPath.Shared.Activities /// /// Taken from System Activities /// - public static class PathExtensions + internal static class PathExtensions { /// /// Returns true if the given path does not contain any invalid characters, false otherwise. @@ -27,7 +27,7 @@ public static bool IsPathValid(this string path) /// public static string AdjustPathSeparator(this string originalPath) { - return originalPath?.Replace('\\', Path.DirectorySeparatorChar)?.Replace('/', Path.DirectorySeparatorChar); + return originalPath?.Replace('\\', Path.DirectorySeparatorChar).Replace('/', Path.DirectorySeparatorChar); } public static bool PathContainsInvalidCharacters(this string path) diff --git a/Activities/Shared/UiPath.Shared.Activities/UiPath.Shared.Activities.projitems b/Activities/Shared/UiPath.Shared.Activities/UiPath.Shared.Activities.projitems index 104074d16..c4421d491 100644 --- a/Activities/Shared/UiPath.Shared.Activities/UiPath.Shared.Activities.projitems +++ b/Activities/Shared/UiPath.Shared.Activities/UiPath.Shared.Activities.projitems @@ -12,6 +12,7 @@ + diff --git a/Activities/Shared/UiPath.Shared/LocalizedEnum.cs b/Activities/Shared/UiPath.Shared/LocalizedEnum.cs index cb94f52d1..6ca516785 100644 --- a/Activities/Shared/UiPath.Shared/LocalizedEnum.cs +++ b/Activities/Shared/UiPath.Shared/LocalizedEnum.cs @@ -5,7 +5,7 @@ namespace UiPath.Shared { - public class LocalizedEnum + internal class LocalizedEnum { public string Name { get; private set; } public Enum Value { get; private set; } @@ -41,7 +41,7 @@ public static LocalizedEnum GetLocalizedValue(Type enumType, object value) } } - public class LocalizedEnum : LocalizedEnum + internal class LocalizedEnum : LocalizedEnum { protected LocalizedEnum(string name, Enum value) : base(name, value) { diff --git a/Activities/Shared/UiPath.Shared/SystemExtensions.cs b/Activities/Shared/UiPath.Shared/SystemExtensions.cs index 29dc74e9c..5a4117c78 100644 --- a/Activities/Shared/UiPath.Shared/SystemExtensions.cs +++ b/Activities/Shared/UiPath.Shared/SystemExtensions.cs @@ -7,7 +7,7 @@ namespace System { - public static class Extensions + internal static class Extensions { public static bool IsNullOrEmpty(this string value) { @@ -19,9 +19,9 @@ public static IComparer ToComparer(this Func compare) return new Comparer(compare); } - private class Comparer : IComparer + private sealed class Comparer : IComparer { - private Func _compare; + private readonly Func _compare; public Comparer(Func comparison) { _compare = comparison; @@ -45,7 +45,7 @@ public static IDisposable DisposeWith(this T obj, Action onDispose, out T public static IDisposable DisposeWith(this T obj, Action onDispose) { - if (obj == null) + if (object.Equals(obj, default(T))) { return Disposable.Empty; } @@ -62,10 +62,10 @@ public static IDisposable DisposeWithReleaseComObject(this T obj) return DisposeWith(obj, (onDispose) => Marshal.ReleaseComObject(obj)); } - private class Disposable : IDisposable + private sealed class Disposable : IDisposable { - public static Disposable Empty = new Disposable(null) { _disposed = true }; - private Action _onDispose; + public static readonly Disposable Empty = new Disposable(null) { _disposed = true }; + private readonly Action _onDispose; public Disposable(Action onDispose) { _onDispose = onDispose; @@ -129,7 +129,7 @@ public static async Task RetryAsync(this Func> func, Func(this IEnumerable source) { @@ -173,13 +173,13 @@ public static TValue Get(this IDictionary source, TK return value; } return null; - } + } } } namespace System.IO { - public static class Extensions + internal static class Extensions { public static byte[] ReadToEnd(this Stream stream, int chunkSize = 1024) { @@ -216,7 +216,7 @@ public static byte[] ReadToEnd(this Stream stream, int chunkSize = 1024) namespace System.Threading.Tasks { - public static class TaskExtensions + internal static class TaskExtensions { [Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters", MessageId = "task")] public static void DoNotAwait(this Task task)