WebFileServer
Changes
.gitignore 28(+28 -0)
FileServer/.vs/FileServer/v15/.suo 0(+0 -0)
FileServer/BLL/App.config 17(+17 -0)
FileServer/BLL/Base/BaseServices.cs 21(+21 -0)
FileServer/BLL/BLL.csproj 71(+71 -0)
FileServer/BLL/BLL.csproj.user 6(+6 -0)
FileServer/BLL/packages.config 4(+4 -0)
FileServer/BLL/Properties/AssemblyInfo.cs 36(+36 -0)
FileServer/BLL/Services/ScanServices.cs 186(+186 -0)
FileServer/BLL/Services/UploadServices.cs 66(+66 -0)
FileServer/Console/App.config 24(+24 -0)
FileServer/Console/Console.csproj 71(+71 -0)
FileServer/Console/packages.config 4(+4 -0)
FileServer/Console/Program.cs 128(+128 -0)
FileServer/FileServer.sln 53(+53 -0)
FileServer/Model/App.config 17(+17 -0)
FileServer/Model/Entities/Base/BaseEntity.cs 32(+32 -0)
FileServer/Model/Entities/Base/I_Entity.cs 14(+14 -0)
FileServer/Model/Entities/Files/FS_Item.cs 148(+148 -0)
FileServer/Model/Entities/Users/Group.cs 43(+43 -0)
FileServer/Model/Entities/Users/User.cs 25(+25 -0)
FileServer/Model/Model.csproj 83(+83 -0)
FileServer/Model/Model.csproj.user 6(+6 -0)
FileServer/Model/packages.config 4(+4 -0)
FileServer/Model/Properties/AssemblyInfo.cs 36(+36 -0)
FileServer/Model/UnitsOfWork/Context.cs 58(+58 -0)
FileServer/Model/UnitsOfWork/UOW.cs 64(+64 -0)
FileServer/Web/App_Start/BundleConfig.cs 30(+30 -0)
FileServer/Web/App_Start/FilterConfig.cs 13(+13 -0)
FileServer/Web/App_Start/RouteConfig.cs 23(+23 -0)
FileServer/Web/App_Start/WebApiConfig.cs 21(+21 -0)
FileServer/Web/Controllers/API/ExplorerController.cs 182(+182 -0)
FileServer/Web/Controllers/HomeController.cs 36(+36 -0)
FileServer/Web/favicon.ico 0(+0 -0)
FileServer/Web/Global.asax 1(+1 -0)
FileServer/Web/Global.asax.cs 44(+44 -0)
FileServer/Web/Models/Base/BaseApiResult.cs 21(+21 -0)
FileServer/Web/packages.config 30(+30 -0)
FileServer/Web/Properties/AssemblyInfo.cs 35(+35 -0)
FileServer/Web/Scripts/React/App.jsx 81(+81 -0)
FileServer/Web/Scripts/React/FileExplorerControl.jsx 165(+165 -0)
FileServer/Web/Scripts/React/RouteSystem.jsx 27(+27 -0)
FileServer/Web/Scripts/React/UploaderControl.jsx 101(+101 -0)
FileServer/Web/Scripts/React/UserControl.jsx 78(+78 -0)
FileServer/Web/Scripts/Services/UploadServices.js 149(+149 -0)
FileServer/Web/Scripts/Tools/Sort.js 64(+64 -0)
FileServer/Web/Views/Home/Contact.cshtml 17(+17 -0)
FileServer/Web/Views/Home/Index.cshtml 69(+69 -0)
FileServer/Web/Views/Shared/_Layout.cshtml 44(+44 -0)
FileServer/Web/Views/Shared/Error.cshtml 14(+14 -0)
FileServer/Web/Views/Web.config 43(+43 -0)
FileServer/Web/Web.config 117(+117 -0)
FileServer/Web/Web.csproj 311(+311 -0)
FileServer/Web/Web.csproj.user 49(+49 -0)
FileServer/Web/Web.Debug.config 30(+30 -0)
FileServer/Web/Web.Release.config 31(+31 -0)
Details
.gitignore 28(+28 -0)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..d9ae6e1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,28 @@
+
+FileServer/.vs/config/applicationhost.config
+FileServer/.vs/FileServer/v15/Server
+
+FileServer/packages
+
+
+FileServer/BLL/bin
+FileServer/BLL/obj
+
+
+FileServer/Console/bin
+FileServer/Console/obj
+
+
+FileServer/Model/bin
+FileServer/Model/obj
+
+
+FileServer/Web/bin
+FileServer/Web/obj
+
+FileServer/Web/Scripts/*
+!FileServer/Web/Scripts/React/
+!FileServer/Web/Scripts/Services/
+!FileServer/Web/Scripts/Tools/
+
+FileServer/Web/Content
FileServer/.vs/FileServer/v15/.suo 0(+0 -0)
diff --git a/FileServer/.vs/FileServer/v15/.suo b/FileServer/.vs/FileServer/v15/.suo
new file mode 100644
index 0000000..6edc2ed
Binary files /dev/null and b/FileServer/.vs/FileServer/v15/.suo differ
FileServer/BLL/App.config 17(+17 -0)
diff --git a/FileServer/BLL/App.config b/FileServer/BLL/App.config
new file mode 100644
index 0000000..7e1d79c
--- /dev/null
+++ b/FileServer/BLL/App.config
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+ <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+ </configSections>
+ <entityFramework>
+ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
+ <parameters>
+ <parameter value="mssqllocaldb" />
+ </parameters>
+ </defaultConnectionFactory>
+ <providers>
+ <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+ </providers>
+ </entityFramework>
+</configuration>
\ No newline at end of file
FileServer/BLL/Base/BaseServices.cs 21(+21 -0)
diff --git a/FileServer/BLL/Base/BaseServices.cs b/FileServer/BLL/Base/BaseServices.cs
new file mode 100644
index 0000000..fc5a76c
--- /dev/null
+++ b/FileServer/BLL/Base/BaseServices.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Model.UnitsOfWork;
+
+namespace BLL.Base
+{
+ public abstract class BaseServices
+ {
+ public readonly UOW UOW;
+
+ public BaseServices(UOW UOW)
+ {
+ this.UOW = UOW;
+ }
+
+ }
+}
FileServer/BLL/BLL.csproj 71(+71 -0)
diff --git a/FileServer/BLL/BLL.csproj b/FileServer/BLL/BLL.csproj
new file mode 100644
index 0000000..733abb9
--- /dev/null
+++ b/FileServer/BLL/BLL.csproj
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{B03D6843-E0CD-4526-990D-0300E8B148EC}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>BLL</RootNamespace>
+ <AssemblyName>BLL</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <Deterministic>true</Deterministic>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.DataAnnotations" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Numerics" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Base\BaseServices.cs" />
+ <Compile Include="Services\GarbageUploadServices.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="Services\ConfigurationServices.cs" />
+ <Compile Include="Services\ScanServices.cs" />
+ <Compile Include="Services\UploadServices.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\Model\Model.csproj">
+ <Project>{156c9263-5079-445d-b579-3540ca1b54b1}</Project>
+ <Name>Model</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
FileServer/BLL/BLL.csproj.user 6(+6 -0)
diff --git a/FileServer/BLL/BLL.csproj.user b/FileServer/BLL/BLL.csproj.user
new file mode 100644
index 0000000..6cbe588
--- /dev/null
+++ b/FileServer/BLL/BLL.csproj.user
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectView>ProjectFiles</ProjectView>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
FileServer/BLL/packages.config 4(+4 -0)
diff --git a/FileServer/BLL/packages.config b/FileServer/BLL/packages.config
new file mode 100644
index 0000000..d8c7306
--- /dev/null
+++ b/FileServer/BLL/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="EntityFramework" version="6.2.0" targetFramework="net45" />
+</packages>
\ No newline at end of file
FileServer/BLL/Properties/AssemblyInfo.cs 36(+36 -0)
diff --git a/FileServer/BLL/Properties/AssemblyInfo.cs b/FileServer/BLL/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..43a6b37
--- /dev/null
+++ b/FileServer/BLL/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Общие сведения об этой сборке предоставляются следующим набором
+// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
+// связанные со сборкой.
+[assembly: AssemblyTitle("BLL")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("BLL")]
+[assembly: AssemblyCopyright("Copyright © 2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
+// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
+// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
+[assembly: ComVisible(false)]
+
+// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
+[assembly: Guid("b03d6843-e0cd-4526-990d-0300e8b148ec")]
+
+// Сведения о версии сборки состоят из следующих четырех значений:
+//
+// Основной номер версии
+// Дополнительный номер версии
+// Номер сборки
+// Редакция
+//
+// Можно задать все значения или принять номер сборки и номер редакции по умолчанию.
+// используя "*", как показано ниже:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/FileServer/BLL/Services/ConfigurationServices.cs b/FileServer/BLL/Services/ConfigurationServices.cs
new file mode 100644
index 0000000..1c89670
--- /dev/null
+++ b/FileServer/BLL/Services/ConfigurationServices.cs
@@ -0,0 +1,50 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.IO;
+using System.Configuration;
+
+using BLL.Base;
+
+using Model.UnitsOfWork;
+using Model.Entities.Files.FS_Entities;
+using Model.Entities.Files.Repo;
+
+namespace BLL.Services
+{
+ public class ConfigurationServices : BaseServices
+ {
+ const string FolderPrefix = "WorkFolder";
+
+ public ConfigurationServices(UOW uOW) : base(uOW) { }
+
+
+ public void ReadConfiguration()
+ {
+ var config = ConfigurationManager.AppSettings;
+
+ var folder_values = new LinkedList<string>(config.GetValues(FolderPrefix).First().Split(';'));
+ var db_dir = UOW.Repo_rootDirectory.All;
+
+ foreach (var elem in db_dir)
+ {
+ if (!folder_values.Contains(elem.PhysicalPath))
+ UOW.Repo_rootDirectory.DeleteInList(elem);
+ else
+ folder_values.Remove(elem.PhysicalPath);
+ }
+
+ if (folder_values.Count != 0)
+ {
+ var nRoot = new List<SRootDirectory>(folder_values.Count);
+
+ foreach (var elem in folder_values)
+ nRoot.Add(UOW.Repo_rootDirectory.
+ Create(new SRootDirectory(elem, Path.GetFileName(elem))));
+ }
+ }
+ }
+}
diff --git a/FileServer/BLL/Services/GarbageUploadServices.cs b/FileServer/BLL/Services/GarbageUploadServices.cs
new file mode 100644
index 0000000..a5aca85
--- /dev/null
+++ b/FileServer/BLL/Services/GarbageUploadServices.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.Data.Entity;
+
+using BLL.Base;
+
+using Model.UnitsOfWork;
+using Model.Entities.Files.FS_Entities;
+
+namespace BLL.Services
+{
+ public class GarbageUploadServices : BaseServices
+ {
+ readonly static TimeSpan UploadDeadTimeout = new TimeSpan(0, 5, 0);
+
+ public GarbageUploadServices(UOW UOW) : base(UOW) { }
+
+
+ public async Task<int> DeleteDeadAsync()
+ {
+ return await Task.Run(() => DeleteDead());
+ }
+
+ /// <summary>
+ /// Выполняет удаление
+ /// </summary>
+ /// <returns></returns>
+ public int DeleteDead()
+ {
+ var now = DateTime.Now;
+
+ var dead_uploads = UOW.Repo_SFileUpload.All_List.
+ Where(e => (e.LastChunkUploaded - now) > UploadDeadTimeout);
+
+ foreach (var elem in dead_uploads)
+ UOW.Repo_SFileUpload.Delete(elem);
+
+ return dead_uploads.Count();
+ }
+
+ }
+}
FileServer/BLL/Services/ScanServices.cs 186(+186 -0)
diff --git a/FileServer/BLL/Services/ScanServices.cs b/FileServer/BLL/Services/ScanServices.cs
new file mode 100644
index 0000000..a92ec84
--- /dev/null
+++ b/FileServer/BLL/Services/ScanServices.cs
@@ -0,0 +1,186 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.IO;
+
+using BLL.Base;
+
+using Model.UnitsOfWork;
+using Model.Entities.Files.FS_Entities;
+using Model.Entities.Files;
+
+namespace BLL.Services
+{
+ public class ScanServices : BaseServices
+ {
+ public ScanServices(UOW uOW) : base(uOW) { }
+
+
+ ///// <summary>
+ ///// Для паралельной работы для каждого параллельного исполнения
+ ///// нужен свой контекст и uow
+ ///// С точки зрения зависимостей очень кривая реализация
+ ///// </summary>
+ ///// <param name="IsParalle"></param>
+ ///// <returns></returns>
+ //private UOW GetUnit(bool IsParalle)
+ //{
+ // return !IsParalle ? UOW : new UOW();
+ //}
+
+
+
+ /// <summary>
+ /// Запускает полное сконирование базы от коренных папок
+ /// Для корекнных папок в случае отцутствия создается папка
+ /// </summary>
+ /// <param name="IsParalle"></param>
+ /// <returns></returns>
+ public async Task ScanAllDirs()//bool IsParalle = false)
+ {
+ await Task.Run(async () =>
+ {
+ await RecursScanDirectoryAsync(UOW.Repo_rootDirectory.All.ToArray(), true);//, IsParalle);
+ });
+ }
+
+
+
+ public async Task RecursScanDirectoryAsync(IEnumerable<SDirectory> directorys, bool Recursive = true)//, bool IsParalle = false)
+ {
+ await Task.Run(async () =>
+ {
+ //Не параллельно
+ //if (!IsParalle)
+ //{
+ foreach (var elem in directorys)
+ await RecursScanDirectoryAsync(elem, true);//, IsParalle);
+ //}
+ ////Параллельно
+ //else
+ //{
+ // var tasks = new List<Task>(directorys.Count());
+
+ // foreach (var elem in directorys)
+ // tasks.Add(RecursScanDirectoryAsync(elem, true, IsParalle));
+
+ // await Task.WhenAll(tasks);
+ //}
+ });
+ }
+
+
+ /// <summary>
+ /// Сравнивает содержимое файловой системы и базы
+ /// Приводя их в единый вид по правилу:
+ /// 1) Если есть в базе, но нет в ФС, то удалить из базы
+ /// 2) Если есть в ФС, но нет в базе, то добавить в базу
+ /// </summary>
+ /// <param name="directory"></param>
+ /// <param name="Recursive"></param>
+ /// <param name="IsParalle"></param>
+ /// <returns></returns>
+ public async Task RecursScanDirectoryAsync(SDirectory directory, bool Recursive = true)//, bool IsParalle = false)
+ {
+ await Task.Run(async () =>
+ {
+ //var uow = GetUnit(IsParalle);
+
+ //Если папка коренная то проверить наличие и если нет, то создать
+ if (directory.IsRoot)
+ {
+ if (Directory.Exists(directory.PhysicalPath))
+ Directory.CreateDirectory(directory.PhysicalPath);
+ }
+
+ //Данные о папке из базы
+ var db = new
+ {
+ files = directory.Files.ToList(),
+ dirs = directory.Directories.ToList(),
+ upload = directory.UploadFiles.ToList(),
+ };
+
+ //Данные о папке из файловой системы
+ var fs = new
+ {
+ files = new LinkedList<string>(
+ Directory.GetFiles(directory.PhysicalPath).
+ Select(e => Path.GetFileName(e))
+ ),
+ dirs = new LinkedList<string>(
+ Directory.GetDirectories(directory.PhysicalPath).
+ Select(e => Path.GetFileName(e))
+ )
+ };
+
+
+ foreach (var elem in db.files)
+ {
+ //Если файл из базы не найден в фс
+ if (!fs.files.Contains(elem.Name))
+ UOW.Repo_SFile.DeleteInList(elem);
+ //Если файл найден, то удаляем из списка файловой системы
+ else
+ fs.files.Remove(elem.Name);
+ }
+
+ //Если в файловой системе есть файлы, не зафиксированные в базе
+ if (fs.files.Count != 0)
+ {
+ var upload_name = db.upload.Select(e => e.Name);
+
+ foreach (var elem in fs.files)
+ {
+ //Файл находится в стадии загрузки
+ if (upload_name.Contains(elem))
+ continue;
+
+ //Файл вносится в базу
+ FileInfo file = new FileInfo(Path.Combine(directory.PhysicalPath, elem));
+ db.files.Add(UOW.Repo_SFile.Create(new SFile(directory, file.Name, file.Length)));
+ }
+ }
+
+
+ foreach (var elem in db.dirs)
+ {
+ //Если папка из базы не найден в фс
+ if (!fs.dirs.Contains(elem.Name))
+ {
+ UOW.Repo_SDirectory.DeleteInList(elem);
+ }
+ //Если папка найден, то удаляем из списка файловой системы
+ else
+ fs.dirs.Remove(elem.Name);
+ }
+
+ //Если в файловой системе есть папки, не зафиксированные в базе
+ if (fs.dirs.Count != 0)
+ {
+ foreach (var elem in fs.dirs)
+ {
+ db.dirs.Add(UOW.Repo_SDirectory.Create(new SDirectory(directory, elem)));
+ }
+ }
+
+ fs.files.Clear();
+ fs.dirs.Clear();
+
+ db.files.Clear();
+ db.upload.Clear();
+
+ //Рекурсивно вызвать сканирование для подпапок
+ if (Recursive)
+ await RecursScanDirectoryAsync(db.dirs, true);//, IsParalle);
+
+ db.dirs.Clear();
+ });
+ }
+
+
+ }
+}
FileServer/BLL/Services/UploadServices.cs 66(+66 -0)
diff --git a/FileServer/BLL/Services/UploadServices.cs b/FileServer/BLL/Services/UploadServices.cs
new file mode 100644
index 0000000..f08a07b
--- /dev/null
+++ b/FileServer/BLL/Services/UploadServices.cs
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using BLL.Base;
+
+using Model.UnitsOfWork;
+using Model.Entities.Files.FS_Entities;
+using Model.Entities.Files.Repo;
+
+namespace BLL.Services
+{
+
+
+ public class UploadServices : BaseServices
+ {
+ const int ChunkSize = 102400;
+ protected readonly Repo_SFileUpload Repo_SFileUpload;
+
+ public UploadServices(UOW UOW) : base(UOW)
+ {
+ Repo_SFileUpload = UOW.Repo_SFileUpload;
+ }
+
+ public SFileUpload StartUpload(SDirectory directory, string Name, long size)
+ {
+ var res = Repo_SFileUpload.Create(
+ new SFileUpload(directory, Name, size, ChunkSize));
+
+ return res;
+ }
+ public bool UploadChunk(SFileUpload project, byte[] data)
+ {
+ project.CurrentChunk = data;
+
+ Repo_SFileUpload.Update(project);
+
+
+ if (project.UploadProgress == 100)
+ {
+ Done(project);
+ return true;
+ }
+
+ return false;
+ }
+
+ public void Cansel(SFileUpload project)
+ {
+ Repo_SFileUpload.Delete(project);
+ }
+
+ private void Done(SFileUpload project)
+ {
+ var p = project.Parent;
+
+ Repo_SFileUpload.DeleteInList(project);
+
+ UOW.Repo_SFile.Create(
+ new SFile(p, project.Name, (long)project.Size));
+ }
+
+ }
+}
FileServer/Console/App.config 24(+24 -0)
diff --git a/FileServer/Console/App.config b/FileServer/Console/App.config
new file mode 100644
index 0000000..af887af
--- /dev/null
+++ b/FileServer/Console/App.config
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+ <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+ </configSections>
+ <startup>
+ <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+ </startup>
+ <entityFramework>
+ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
+ <parameters>
+ <parameter value="mssqllocaldb" />
+ </parameters>
+ </defaultConnectionFactory>
+ <providers>
+ <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+ </providers>
+ </entityFramework>
+
+ <appSettings>
+ <add key="WorkFolder" value="C:\Users\cccc1808\source\repos\FileServer\Console\bin\Debug\Dir1;C:\Users\cccc1808\source\repos\FileServer\Console\bin\Debug\Dir2" />
+ </appSettings>
+</configuration>
\ No newline at end of file
FileServer/Console/Console.csproj 71(+71 -0)
diff --git a/FileServer/Console/Console.csproj b/FileServer/Console/Console.csproj
new file mode 100644
index 0000000..f5a7c84
--- /dev/null
+++ b/FileServer/Console/Console.csproj
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{2E564B56-BCBD-423E-A2D7-53F6D53D8AA3}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <RootNamespace>Console</RootNamespace>
+ <AssemblyName>Console</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <Deterministic>true</Deterministic>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <PlatformTarget>AnyCPU</PlatformTarget>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.DataAnnotations" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Numerics" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Program.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="App.config" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\BLL\BLL.csproj">
+ <Project>{b03d6843-e0cd-4526-990d-0300e8b148ec}</Project>
+ <Name>BLL</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Model\Model.csproj">
+ <Project>{156c9263-5079-445d-b579-3540ca1b54b1}</Project>
+ <Name>Model</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
FileServer/Console/packages.config 4(+4 -0)
diff --git a/FileServer/Console/packages.config b/FileServer/Console/packages.config
new file mode 100644
index 0000000..d8c7306
--- /dev/null
+++ b/FileServer/Console/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="EntityFramework" version="6.2.0" targetFramework="net45" />
+</packages>
\ No newline at end of file
FileServer/Console/Program.cs 128(+128 -0)
diff --git a/FileServer/Console/Program.cs b/FileServer/Console/Program.cs
new file mode 100644
index 0000000..d887699
--- /dev/null
+++ b/FileServer/Console/Program.cs
@@ -0,0 +1,128 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Model.UnitsOfWork;
+using Model.Entities.Files;
+using Model.Entities.Files.FS_Entities;
+using BLL.Services;
+
+using System.IO;
+using System.Data.Entity;
+
+namespace Console
+{
+ class Program
+ {
+ static void test1()
+ {
+ //using (Context context = new Context(true))
+ //{
+ // SRootDirectory rootDirectory = new SRootDirectory(@"D:\", "Root");
+ // context.FS_Items.Add(rootDirectory);
+
+
+ // SDirectory directory1 = new SDirectory()
+ // {
+ // Parent = rootDirectory,
+ // Name = "Dir1"
+ // };
+ // context.FS_Items.Add(directory1);
+
+ // SDirectory directory2 = new SDirectory()
+ // {
+ // Parent = rootDirectory,
+ // Name = "Dir2"
+ // };
+ // context.FS_Items.Add(directory2);
+
+
+
+ // SFile file1 = new SFile()
+ // {
+ // Parent = rootDirectory,
+ // Name = "file1.file",
+ // _Size = 10,
+ // };
+ // context.FS_Items.Add(file1);
+
+
+ // SFile file12 = new SFile()
+ // {
+ // Parent = directory1,
+ // Name = "file12.file",
+ // _Size = 10,
+ // };
+ // context.FS_Items.Add(file12);
+ // SFile file13 = new SFile()
+ // {
+ // Parent = directory1,
+ // Name = "file13.file",
+ // _Size = 123,
+ // };
+ // context.FS_Items.Add(file13);
+
+ // context.SaveChanges();
+ //}
+
+
+ //using (Context context = new Context())
+ //{
+ // //var data = context.FS_Items.ToList();//.Include("_Items").Include(e => e.Parent).AsNoTracking().ToList();
+ // //var d = data[0].Size;
+
+ // var root = context.FS_Items.FirstOrDefault(e => e.Type == Enum_BaseDirectoryEntity.RootDirectory);
+ // var size = root.Size;
+ //}
+
+ UOW UOW = new UOW();
+
+
+ ConfigurationServices configurationServices = new ConfigurationServices(UOW);
+ configurationServices.ReadConfiguration();
+
+
+ var files = UOW.context.FS_Items.ToList();
+ }
+
+ static void Test2()
+ {
+ var UploadFile = new FileInfo(@"D:\Links.txt");
+
+ using (var context = new Context(true)) { }
+
+
+ UOW UOW = new UOW();
+
+ new ConfigurationServices(UOW).ReadConfiguration();
+
+
+ UploadServices uploadServices = new UploadServices(UOW);
+
+
+ var upload = uploadServices.StartUpload(
+ UOW.Repo_rootDirectory.All.First(), UploadFile.Name, UploadFile.Length);
+
+ using (var stream = new FileStream(UploadFile.FullName, FileMode.Open, FileAccess.Read))
+ {
+ byte[] data = new byte[upload.NextChunkSize];
+
+ do
+ {
+ stream.Read(data, (int)upload.UploadedSize, upload.NextChunkSize);
+ } while (uploadServices.UploadChunk(upload, data));
+ }
+ }
+
+ static void Main(string[] args)
+ {
+ new Context(true);
+
+ var UOW = new UOW();
+ new ConfigurationServices(UOW).ReadConfiguration();
+ Task.WaitAll(new ScanServices(UOW).ScanAllDirs());
+ }
+ }
+}
diff --git a/FileServer/Console/Properties/AssemblyInfo.cs b/FileServer/Console/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..df73c73
--- /dev/null
+++ b/FileServer/Console/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Общие сведения об этой сборке предоставляются следующим набором
+// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
+// связанные со сборкой.
+[assembly: AssemblyTitle("Console")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Console")]
+[assembly: AssemblyCopyright("Copyright © 2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
+// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
+// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
+[assembly: ComVisible(false)]
+
+// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
+[assembly: Guid("2e564b56-bcbd-423e-a2d7-53f6d53d8aa3")]
+
+// Сведения о версии сборки состоят из следующих четырех значений:
+//
+// Основной номер версии
+// Дополнительный номер версии
+// Номер сборки
+// Редакция
+//
+// Можно задать все значения или принять номер сборки и номер редакции по умолчанию.
+// используя "*", как показано ниже:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
FileServer/FileServer.sln 53(+53 -0)
diff --git a/FileServer/FileServer.sln b/FileServer/FileServer.sln
new file mode 100644
index 0000000..92029f4
--- /dev/null
+++ b/FileServer/FileServer.sln
@@ -0,0 +1,53 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.136
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Console", "Console\Console.csproj", "{2E564B56-BCBD-423E-A2D7-53F6D53D8AA3}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Model", "Model\Model.csproj", "{156C9263-5079-445D-B579-3540CA1B54B1}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Domain", "Domain", "{92CC88D7-8784-497B-9146-0E02FD783110}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Controller", "Controller", "{7F3E17AA-FA4A-43AC-8EA2-69F833002500}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BLL", "BLL\BLL.csproj", "{B03D6843-E0CD-4526-990D-0300E8B148EC}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Web", "Web\Web.csproj", "{18878028-6360-4299-88FC-2A3B3A45E3A8}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2E564B56-BCBD-423E-A2D7-53F6D53D8AA3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2E564B56-BCBD-423E-A2D7-53F6D53D8AA3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2E564B56-BCBD-423E-A2D7-53F6D53D8AA3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2E564B56-BCBD-423E-A2D7-53F6D53D8AA3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {156C9263-5079-445D-B579-3540CA1B54B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {156C9263-5079-445D-B579-3540CA1B54B1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {156C9263-5079-445D-B579-3540CA1B54B1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {156C9263-5079-445D-B579-3540CA1B54B1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B03D6843-E0CD-4526-990D-0300E8B148EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B03D6843-E0CD-4526-990D-0300E8B148EC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B03D6843-E0CD-4526-990D-0300E8B148EC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B03D6843-E0CD-4526-990D-0300E8B148EC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {18878028-6360-4299-88FC-2A3B3A45E3A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18878028-6360-4299-88FC-2A3B3A45E3A8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18878028-6360-4299-88FC-2A3B3A45E3A8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18878028-6360-4299-88FC-2A3B3A45E3A8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(NestedProjects) = preSolution
+ {2E564B56-BCBD-423E-A2D7-53F6D53D8AA3} = {7F3E17AA-FA4A-43AC-8EA2-69F833002500}
+ {156C9263-5079-445D-B579-3540CA1B54B1} = {92CC88D7-8784-497B-9146-0E02FD783110}
+ {B03D6843-E0CD-4526-990D-0300E8B148EC} = {92CC88D7-8784-497B-9146-0E02FD783110}
+ {18878028-6360-4299-88FC-2A3B3A45E3A8} = {7F3E17AA-FA4A-43AC-8EA2-69F833002500}
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {3BDB4E41-3C9F-4326-B453-03CE5954033F}
+ EndGlobalSection
+EndGlobal
FileServer/Model/App.config 17(+17 -0)
diff --git a/FileServer/Model/App.config b/FileServer/Model/App.config
new file mode 100644
index 0000000..7e1d79c
--- /dev/null
+++ b/FileServer/Model/App.config
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<configuration>
+ <configSections>
+ <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+ <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+ </configSections>
+ <entityFramework>
+ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
+ <parameters>
+ <parameter value="mssqllocaldb" />
+ </parameters>
+ </defaultConnectionFactory>
+ <providers>
+ <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+ </providers>
+ </entityFramework>
+</configuration>
\ No newline at end of file
diff --git a/FileServer/Model/Entities/Base/Base_FS_Repository.cs b/FileServer/Model/Entities/Base/Base_FS_Repository.cs
new file mode 100644
index 0000000..ddaef32
--- /dev/null
+++ b/FileServer/Model/Entities/Base/Base_FS_Repository.cs
@@ -0,0 +1,47 @@
+using System;
+using System.Collections.Generic;
+using System.Data.Entity;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Model.Entities.Files;
+using Model.UnitsOfWork;
+
+namespace Model.Entities.Base
+{
+ public abstract class Base_FS_Repository<T> : BaseRepository<T> where T : FS_Item
+ {
+ public DbSet<FS_Item> Set_Fs => context.Set<FS_Item>();
+
+
+ public Base_FS_Repository(Context context) : base(context) { }
+
+ /// <summary>
+ /// Рекурсия
+ /// Функция удаляет данные о файлах из базы, при этом не влияя на ФС
+ /// Обычно вызывается при сканировании ФС, когда папка/файл из базы не найдена в ФС
+ /// </summary>
+ /// <param name="elem"></param>
+ public void DeleteInList(FS_Item elem)
+ {
+ foreach (var item in elem.Items)
+ {
+ _DeleteInList(item);
+ }
+
+ Set_Fs.Remove(elem);
+ context.SaveChanges();
+ }
+
+ private void _DeleteInList(FS_Item elem)
+ {
+ foreach (var item in elem.Items)
+ {
+ DeleteInList(item);
+ }
+ Set_Fs.Remove(elem);
+ }
+
+ }
+}
FileServer/Model/Entities/Base/BaseEntity.cs 32(+32 -0)
diff --git a/FileServer/Model/Entities/Base/BaseEntity.cs b/FileServer/Model/Entities/Base/BaseEntity.cs
new file mode 100644
index 0000000..cf36ea8
--- /dev/null
+++ b/FileServer/Model/Entities/Base/BaseEntity.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+
+namespace Model.Entities.Base
+{
+ public abstract class BaseEntity
+ {
+ //[Key]
+ public int ID { set; get; }
+
+ [Column(TypeName = "datetime2")]
+ public DateTime CreateDate { set; get; }
+
+
+ private void Init()
+ {
+ this.CreateDate = DateTime.Now;
+ }
+
+ public BaseEntity()
+ {
+ Init();
+ }
+
+ }
+}
diff --git a/FileServer/Model/Entities/Base/BaseRepository.cs b/FileServer/Model/Entities/Base/BaseRepository.cs
new file mode 100644
index 0000000..f1e0e7b
--- /dev/null
+++ b/FileServer/Model/Entities/Base/BaseRepository.cs
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.Data.Entity;
+
+using Model.Entities.Base;
+using Model.Entities.Files;
+using Model.UnitsOfWork;
+
+
+namespace Model.Entities.Base
+{
+ public abstract class BaseRepository<T> where T : BaseEntity
+ {
+ public readonly Context context;
+
+ public BaseRepository(Context context)
+ {
+ this.context = context;
+ }
+
+
+ protected DbSet<T> Set => context.Set<T>();
+ public IQueryable<T> All => Set.AsQueryable();
+ public IQueryable<T> All_NoTrack => Set.AsNoTracking().AsQueryable();
+
+ public List<T> All_List => Set.ToList();
+ public List<T> All_NoTrack_List => Set.AsNoTracking().ToList();
+
+
+ protected abstract void Validation_Create(T elem);
+ public virtual T Create(T elem)
+ {
+ Validation_Create(elem);
+
+ var res = Set.Add(elem);
+ context.SaveChanges();
+
+ return res;
+ }
+
+
+ protected abstract void Validation_Update(T old, T elem);
+ public virtual void Update(T elem)
+ {
+ var change_entity = Set.FirstOrDefault(e => e.ID == elem.ID);
+
+ if (change_entity == null)
+ throw new Exception("old value not found");
+
+ Validation_Update(change_entity, elem);
+
+ context.Entry(change_entity).CurrentValues.SetValues(elem);
+ context.SaveChanges();
+ }
+
+
+ protected abstract void Validation_Delete(T elem);
+ public virtual void Delete(T elem)
+ {
+ Validation_Delete(elem);
+
+ Set.Remove(elem);
+ context.SaveChanges();
+ }
+
+
+ }
+}
FileServer/Model/Entities/Base/I_Entity.cs 14(+14 -0)
diff --git a/FileServer/Model/Entities/Base/I_Entity.cs b/FileServer/Model/Entities/Base/I_Entity.cs
new file mode 100644
index 0000000..613ff8b
--- /dev/null
+++ b/FileServer/Model/Entities/Base/I_Entity.cs
@@ -0,0 +1,14 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Model.Entities.Base
+{
+ public interface I_Entity
+ {
+ int ID { set; get; }
+ DateTime CreateDate { set; get; }
+ }
+}
diff --git a/FileServer/Model/Entities/Base/Repo_Exception.cs b/FileServer/Model/Entities/Base/Repo_Exception.cs
new file mode 100644
index 0000000..13e2943
--- /dev/null
+++ b/FileServer/Model/Entities/Base/Repo_Exception.cs
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Model.Entities.Files;
+
+namespace Model.Entities.Base
+{
+ public class Repo_Exception<T>
+ : Exception where T
+ : BaseEntity
+ {
+ public BaseRepository<T> repository { private set; get; }
+ public FS_Item elem { private set; get; }
+
+ public Repo_Exception(BaseRepository<T> repository, string msg, Exception ex = null)
+ : base(msg, ex)
+ {
+ this.repository = repository;
+ }
+
+ public Repo_Exception(BaseRepository<T> repository, FS_Item elem, string msg, Exception ex = null)
+ : base(msg, ex)
+ {
+ this.repository = repository;
+ this.elem = elem;
+ }
+
+
+ #region
+
+ public static Repo_Exception<T> Factory(BaseRepository<T> repository, FS_Item elem, Repo_Exceptions type)
+ {
+ return new Repo_Exception<T>(repository, elem, type.ToString());
+ }
+ }
+
+ public enum Repo_Exceptions
+ {
+ Name_already_exists_in_parents,
+ Name_is_null_or_empty,
+ Parent_is_null,
+ Elem_items_not_empty,
+ Name_cant_change,
+ File_not_found,
+ Size_not_equils
+ }
+
+ #endregion
+
+ public static class Exception_Extension
+ {
+ public static string FullMessage(this Exception ex)
+ {
+ StringBuilder res = new StringBuilder(ex.Message);
+
+ var e = ex.InnerException;
+ while (e != null)
+ {
+ res.Append("|" + e.Message);
+ e = e.InnerException;
+ }
+
+ return res.ToString();
+ }
+ }
+
+}
diff --git a/FileServer/Model/Entities/Files/FS_Entities/SDirectory.cs b/FileServer/Model/Entities/Files/FS_Entities/SDirectory.cs
new file mode 100644
index 0000000..0e0fd90
--- /dev/null
+++ b/FileServer/Model/Entities/Files/FS_Entities/SDirectory.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.IO;
+using System.Numerics;
+using System.ComponentModel.DataAnnotations.Schema;
+
+using Model.Entities.Base;
+
+namespace Model.Entities.Files.FS_Entities
+{
+ //[NotMapped]
+ public class SDirectory : FS_Item
+ {
+
+ public override bool IsDirectory => true;
+
+ [NotMapped]
+ private DirectoryInfo _Info;
+ public DirectoryInfo Info
+ {
+ get
+ {
+ if (_Info == null)
+ _Info = new DirectoryInfo(PhysicalPath);
+ return _Info; }
+ }
+
+ [Obsolete]
+ public SDirectory() { }
+
+ public SDirectory(SDirectory parent, string Name) : base(Enum_BaseDirectoryEntity.Directory, parent, Name) { }
+ protected SDirectory(Enum_BaseDirectoryEntity type, SDirectory parent, string Name) : base(type, parent, Name) { }
+ }
+}
diff --git a/FileServer/Model/Entities/Files/FS_Entities/SFile.cs b/FileServer/Model/Entities/Files/FS_Entities/SFile.cs
new file mode 100644
index 0000000..783e334
--- /dev/null
+++ b/FileServer/Model/Entities/Files/FS_Entities/SFile.cs
@@ -0,0 +1,54 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.IO;
+using System.ComponentModel.DataAnnotations.Schema;
+
+using Model.Entities.Base;
+using System.Numerics;
+
+namespace Model.Entities.Files.FS_Entities
+{
+ //[NotMapped]
+ public class SFile : FS_Item
+ {
+ //[Column("Size_string")]
+ //public string Size_string { set => _Size = BigInteger.Parse(value); get => _Size.ToString(); }
+
+ [Column("Size")]
+ public long _Size { set; get; }
+
+ public override IReadOnlyList<FS_Item> Items => new List<FS_Item>();
+ public override BigInteger Size => _Size;
+ public override bool IsFile => true;
+
+
+ [NotMapped]
+ private FileInfo _Info;
+ public FileInfo Info
+ {
+ get
+ {
+ if (_Info == null)
+ _Info = new FileInfo(PhysicalPath);
+ return _Info;
+ }
+ }
+
+
+ [Obsolete]
+ public SFile() { }
+
+ public SFile(SDirectory parent, string Name, long size) : base(Enum_BaseDirectoryEntity.File, parent, Name)
+ {
+ this._Size = size;
+ }
+ protected SFile(Enum_BaseDirectoryEntity type, SDirectory parent, string Name, long size) : base(type, parent, Name)
+ {
+ this._Size = size;
+ }
+ }
+}
diff --git a/FileServer/Model/Entities/Files/FS_Entities/SFileUpload.cs b/FileServer/Model/Entities/Files/FS_Entities/SFileUpload.cs
new file mode 100644
index 0000000..1a915eb
--- /dev/null
+++ b/FileServer/Model/Entities/Files/FS_Entities/SFileUpload.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.Numerics;
+using System.ComponentModel.DataAnnotations.Schema;
+
+using Model.Entities.Base;
+using Model.Entities.Files.FS_Entities;
+
+namespace Model.Entities.Files.FS_Entities
+{
+ public class SFileUpload : SFile
+ {
+
+ #region
+
+ [Column("LastChunkUploaded", TypeName = "datetime2")]
+ public DateTime LastChunkUploaded { set; get; }
+
+ //[Column("UploadedSize")]
+ public long UploadedSize { set; get; }
+ //[Column("ChunkSize")]
+ public int ChunkSize { protected set; get; }
+
+ #endregion
+
+
+ public int NextChunkNumber => (int)UploadedSize / ChunkSize;
+ public int NextChunkSize => (int)((UploadedSize + ChunkSize <= Size)
+ ? ChunkSize
+ : Size - UploadedSize);
+ public int UploadProgress => (int)(UploadedSize * 100 / Size);
+
+ [NotMapped]
+ public byte[] CurrentChunk { set; get; }
+
+
+ [Obsolete]
+ public SFileUpload() { }
+
+
+ public SFileUpload(SDirectory parent, string name, long size, int ChunkSize) : base(Enum_BaseDirectoryEntity.UploadFile, parent, name, size)
+ {
+ this.ChunkSize = ChunkSize;
+ }
+
+ }
+}
diff --git a/FileServer/Model/Entities/Files/FS_Entities/SRootDirectory.cs b/FileServer/Model/Entities/Files/FS_Entities/SRootDirectory.cs
new file mode 100644
index 0000000..d1644e5
--- /dev/null
+++ b/FileServer/Model/Entities/Files/FS_Entities/SRootDirectory.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.IO;
+using System.Xml.Serialization;
+using System.ComponentModel.DataAnnotations.Schema;
+
+using Model.Entities.Base;
+using Model.Entities.Users;
+
+namespace Model.Entities.Files.FS_Entities
+{
+ public class Permission
+ {
+ public int GroupID { set; get; }
+ [XmlIgnore]
+ public Group Group { set; get; }
+
+ public bool CanRead { set; get; }
+ public bool CanWrite { set; get; }
+ public bool CanOpen { set; get; }
+ }
+
+ public class DirectoryPermissions
+ {
+ public List<Permission> Permissions { private set; get; } = new List<Permission>();
+
+ public string Export()
+ {
+ XmlSerializer formatter = new XmlSerializer(typeof(Permission[]));
+
+ using (StringWriter wr = new StringWriter())
+ {
+ formatter.Serialize(wr, Permissions.ToArray());
+ return wr.ToString();
+ }
+ }
+ public void Import(string val)
+ {
+ XmlSerializer formatter = new XmlSerializer(typeof(Permission[]));
+
+ using (StringReader rd = new StringReader(val))
+ {
+ Permissions = new List<Permission>(
+ (Permission[])formatter.Deserialize(rd));
+ }
+ }
+ }
+
+
+
+ public class SRootDirectory : SDirectory
+ {
+ /// <summary>
+ /// Укащывается путь к папке
+ /// </summary>
+ public string _PhysicalPath { set; get; }
+
+
+ [Column("XML_Permissions")]
+ public string XML_Permissions
+ {
+ set => DirectoryPermissions.Import(value);
+ get => DirectoryPermissions.Export();
+ }
+ public DirectoryPermissions DirectoryPermissions = new DirectoryPermissions();
+
+
+ public override string PhysicalPath => _PhysicalPath;
+ public override string LogicPath => Path.Combine("\\", Name);
+
+
+
+ [Obsolete("")]
+ public SRootDirectory() { }
+
+ public SRootDirectory(string Path, string Name) : base(Enum_BaseDirectoryEntity.RootDirectory, null, Name)
+ {
+ this._PhysicalPath = Path;
+ }
+
+ }
+}
FileServer/Model/Entities/Files/FS_Item.cs 148(+148 -0)
diff --git a/FileServer/Model/Entities/Files/FS_Item.cs b/FileServer/Model/Entities/Files/FS_Item.cs
new file mode 100644
index 0000000..95d4da5
--- /dev/null
+++ b/FileServer/Model/Entities/Files/FS_Item.cs
@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+
+using System.IO;
+using System.Numerics;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.ComponentModel.DataAnnotations;
+
+using Model.Entities.Base;
+using Model.Entities.Files.FS_Entities;
+
+namespace Model.Entities.Files
+{
+ public enum Enum_FileSize
+ {
+ _byte = 1,
+ Kbyte = 1024,
+ MByte = 1024 * 1024,
+ GByte = 1024 * 1024 * 1024
+ }
+
+
+ public enum Enum_BaseDirectoryEntity
+ {
+ RootDirectory,
+ Directory,
+
+ File,
+ UploadFile
+ }
+
+ public class FS_Item : BaseEntity
+ {
+
+ #region DB_Data
+
+ [Index]
+ [Required]
+ public Enum_BaseDirectoryEntity Type { private set; get; }
+
+ /// <summary>
+ /// Наименование объекта (без пути)
+ /// </summary>
+ ///
+ [Required]
+ public string Name { private set; get; }
+
+
+ /// <summary>
+ /// Коренная папка для данного элемента
+ /// </summary>
+ [ForeignKey("Root")]
+ public int? Root_ID { private set; get; }
+ public virtual SRootDirectory Root { private set; get; }
+
+
+ /// <summary>
+ /// Родителькася папка
+ /// </summary>
+ //[Index]
+ [ForeignKey("Parent")]
+ public int? Parent_ID { private set; get; }
+ //[InverseProperty("")]
+ public virtual SDirectory Parent { private set; get; }
+
+ /// <summary>
+ /// Содержимое папки
+ /// </summary>
+ ///
+ [InverseProperty("Parent")]
+ protected virtual List<FS_Item> _Items { set; get; }
+
+ #endregion
+
+
+ #region GetProperty
+
+ [NotMapped]
+ public virtual IReadOnlyList<FS_Item> Items => _Items ?? new List<FS_Item>();
+
+ [NotMapped]
+ public virtual BigInteger Size => (Items.Count != 0)
+ ? Items.Select(e1 => e1.Size).Aggregate((CurSum, elem) => CurSum + elem)
+ : 0;
+ public double GetSize(Enum_FileSize sizetype, int RoundTo = 3)
+ {
+ return Math.Round(((double)Size / (int)sizetype), RoundTo);
+ }
+
+
+ public virtual bool IsDirectory => false;
+ public virtual bool IsFile => false;
+
+
+ [NotMapped]
+ public bool IsRoot => !Parent_ID.HasValue;
+
+ public bool Contains(FS_Item elem)
+ {
+ return elem.Items.Contains(elem);
+ }
+
+ //public bool ContainsName(SDirectory parent, string Name)
+ //{
+ // return parent.Items.FirstOrDefault(e => e.Name == Name) != null;
+ //}
+ public bool ContainsName(FS_Item elem)
+ {
+ return Items.FirstOrDefault(e => e.Name == elem.Name) != null;
+ }
+
+
+ [NotMapped]
+ public IEnumerable<SFile> Files { get { return (IEnumerable<SFile>)Items.Where(e => e.Type == Enum_BaseDirectoryEntity.File).Cast<SFile>(); } }
+ [NotMapped]
+ public IEnumerable<SDirectory> Directories => Items.Where(e => e.Type == Enum_BaseDirectoryEntity.Directory).Cast<SDirectory>();
+ [NotMapped]
+ public IEnumerable<SFileUpload> UploadFiles => Items.Where(e => e.Type == Enum_BaseDirectoryEntity.UploadFile).Cast<SFileUpload>();
+
+
+ [NotMapped]
+ public virtual string PhysicalPath => Path.Combine(Parent.PhysicalPath, Name);
+ [NotMapped]
+ public virtual string LogicPath => Path.Combine(Parent.LogicPath, Name);
+
+ #endregion
+
+
+ [Obsolete]
+ public FS_Item() { }
+ protected FS_Item(Enum_BaseDirectoryEntity type, SDirectory parent, string Name)
+ {
+ this.Type = type;
+ this.Parent = parent;
+ if (Parent != null)
+ {
+ Root_ID = (parent.IsRoot) ? parent.ID : parent.Root_ID;
+ }
+
+ this.Name = Name;
+ }
+
+ }
+}
diff --git a/FileServer/Model/Entities/Files/Repo/Repo_SDirectory.cs b/FileServer/Model/Entities/Files/Repo/Repo_SDirectory.cs
new file mode 100644
index 0000000..8641ea0
--- /dev/null
+++ b/FileServer/Model/Entities/Files/Repo/Repo_SDirectory.cs
@@ -0,0 +1,77 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.IO;
+
+using Model.Entities.Base;
+using Model.Entities.Files.FS_Entities;
+using Model.UnitsOfWork;
+
+namespace Model.Entities.Files.Repo
+{
+ public class Repo_SDirectory : Base_FS_Repository<SDirectory>
+ {
+ public Repo_SDirectory(Context context) : base(context) { }
+
+ protected override void Validation_Create(SDirectory elem)
+ {
+ if (string.IsNullOrEmpty(elem.Name))
+ throw Repo_Exception<SDirectory>.Factory(this, elem, Repo_Exceptions.Name_is_null_or_empty);
+
+ if (elem.Parent == null)
+ throw Repo_Exception<SDirectory>.Factory(this, elem, Repo_Exceptions.Parent_is_null);
+
+ if (elem.Parent.ContainsName(elem))
+ throw Repo_Exception<SDirectory>.Factory(this, elem, Repo_Exceptions.Name_already_exists_in_parents);
+
+ try
+ {
+ Directory.CreateDirectory(elem.PhysicalPath);
+ }
+ catch (Exception ex)
+ {
+ throw new Repo_Exception<SDirectory>(this, elem, "", ex);
+ }
+ }
+
+ protected override void Validation_Update(SDirectory old, SDirectory elem)
+ {
+ if (elem.Parent == null)
+ throw Repo_Exception<SDirectory>.Factory(this, elem, Repo_Exceptions.Parent_is_null);
+
+ if (old.Name != elem.Name)
+ {
+ if (elem.Parent.ContainsName(elem))
+ if (elem.Parent.ContainsName(elem))
+ throw Repo_Exception<SDirectory>.Factory(this, elem, Repo_Exceptions.Name_already_exists_in_parents);
+
+ try
+ {
+ Directory.Move(old.PhysicalPath, elem.PhysicalPath);
+ }
+ catch (Exception ex)
+ {
+ throw new Repo_Exception<SDirectory>(this, elem, "", ex);
+ }
+ }
+ }
+
+ protected override void Validation_Delete(SDirectory elem)
+ {
+ if (elem.Items.Count() != 0)
+ throw Repo_Exception<SDirectory>.Factory(this, elem, Repo_Exceptions.Elem_items_not_empty);
+
+ try
+ {
+ Directory.Delete(elem.PhysicalPath);
+ }
+ catch (Exception ex)
+ {
+ throw ex;
+ }
+ }
+ }
+}
diff --git a/FileServer/Model/Entities/Files/Repo/Repo_SFile.cs b/FileServer/Model/Entities/Files/Repo/Repo_SFile.cs
new file mode 100644
index 0000000..7918fb5
--- /dev/null
+++ b/FileServer/Model/Entities/Files/Repo/Repo_SFile.cs
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.IO;
+
+using Model.Entities.Base;
+using Model.Entities.Files.FS_Entities;
+using Model.UnitsOfWork;
+
+namespace Model.Entities.Files.Repo
+{
+ public class Repo_SFile : Base_FS_Repository<SFile>
+ {
+ public Repo_SFile(Context context) : base(context) { }
+
+
+ protected override void Validation_Create(SFile elem)
+ {
+ if (string.IsNullOrEmpty(elem.Name))
+ throw new Repo_Exception<SFile>(this, elem, "elem name is null or empty");
+
+ if (elem.Parent == null)
+ throw new Repo_Exception<SFile>(this, elem, "parent is null");
+
+ if (elem.Parent.ContainsName(elem))
+ throw new Repo_Exception<SFile>(this, elem, "parent");
+
+ if (!File.Exists(elem.PhysicalPath))
+ throw new Exception();
+ }
+
+ protected override void Validation_Update(SFile old, SFile elem)
+ {
+ if (elem.Parent == null)
+ throw new Exception();
+
+ if (old.Name != elem.Name)
+ {
+ if (elem.Parent.ContainsName(elem))
+ throw new Exception();
+
+ File.Move(old.PhysicalPath, elem.PhysicalPath);
+ }
+ }
+
+ protected override void Validation_Delete(SFile elem)
+ {
+ File.Delete(elem.PhysicalPath);
+ }
+
+
+
+
+ public FileStream GetFile(SFile elem)
+ {
+ return new FileStream(elem.PhysicalPath, FileMode.Open);
+ }
+
+ }
+}
diff --git a/FileServer/Model/Entities/Files/Repo/Repo_SFileUpload.cs b/FileServer/Model/Entities/Files/Repo/Repo_SFileUpload.cs
new file mode 100644
index 0000000..0bee131
--- /dev/null
+++ b/FileServer/Model/Entities/Files/Repo/Repo_SFileUpload.cs
@@ -0,0 +1,87 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.IO;
+
+using Model.Entities.Base;
+using Model.Entities.Files.FS_Entities;
+using Model.UnitsOfWork;
+
+namespace Model.Entities.Files.Repo
+{
+ public class Repo_SFileUpload : Base_FS_Repository<SFileUpload>
+ {
+
+ public Repo_SFileUpload(Context context) : base(context) { }
+
+ protected override void Validation_Create(SFileUpload elem)
+ {
+ if (string.IsNullOrEmpty(elem.Name))
+ throw Repo_Exception<SFileUpload>.Factory(this, elem, Repo_Exceptions.Name_is_null_or_empty);
+
+ if (elem.Parent == null)
+ throw Repo_Exception<SFileUpload>.Factory(this, elem, Repo_Exceptions.Parent_is_null);
+
+ if (elem.Parent.ContainsName(elem))
+ throw Repo_Exception<SFileUpload>.Factory(this, elem, Repo_Exceptions.Name_already_exists_in_parents);
+
+ try
+ {
+ new FileStream(elem.Info.FullName, FileMode.CreateNew).Close();
+ }
+ catch (Exception ex)
+ {
+ throw new Repo_Exception<SFileUpload>(this, elem, "CreateFile inner ex", ex);
+ }
+ }
+
+ protected override void Validation_Update(SFileUpload old, SFileUpload elem)
+ {
+ if (old.Info.FullName != elem.Info.FullName)
+ throw Repo_Exception<SFileUpload>.Factory(this, elem, Repo_Exceptions.Name_cant_change);
+
+ if (!elem.Info.Exists)
+ throw Repo_Exception<SFileUpload>.Factory(this, elem, Repo_Exceptions.File_not_found);
+
+ if (elem.Info.Length != elem.UploadedSize)
+ throw Repo_Exception<SFileUpload>.Factory(this, elem, Repo_Exceptions.Size_not_equils);
+
+ //Система нескольких попыток доступа к файлу
+ for (int i = 3; i > -1; i--)
+ {
+ try
+ {
+
+ using (var stream = new FileStream(elem.Info.FullName, FileMode.Append, FileAccess.Write))
+ {
+ using (BinaryWriter wr = new BinaryWriter(stream))
+ {
+ wr.Write(elem.CurrentChunk);
+ }
+ }
+
+ break;
+ }
+ catch (Exception ex)
+ {
+ if (i == 0)
+ throw ex;
+
+ System.Threading.Thread.Sleep(100);
+ }
+ }
+
+ elem.UploadedSize += elem.NextChunkSize;
+ }
+
+ protected override void Validation_Delete(SFileUpload elem)
+ {
+ File.Delete(elem.PhysicalPath);
+ }
+
+
+ }
+}
diff --git a/FileServer/Model/Entities/Files/Repo/Repo_SRootDirectory.cs b/FileServer/Model/Entities/Files/Repo/Repo_SRootDirectory.cs
new file mode 100644
index 0000000..c2a595d
--- /dev/null
+++ b/FileServer/Model/Entities/Files/Repo/Repo_SRootDirectory.cs
@@ -0,0 +1,97 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.IO;
+
+using Model.Entities.Base;
+using Model.Entities.Files.FS_Entities;
+using Model.Entities.Users;
+using Model.UnitsOfWork;
+
+namespace Model.Entities.Files.Repo
+{
+
+ public class Repo_SRootDirectory : Base_FS_Repository<SRootDirectory>
+ {
+ public Repo_SRootDirectory(Context context) : base(context) { }
+
+
+ protected override void Validation_Create(SRootDirectory elem)
+ {
+ if (string.IsNullOrEmpty(elem.Name))
+ throw Repo_Exception<SRootDirectory>.Factory(this, elem, Repo_Exceptions.Name_is_null_or_empty);
+
+ if (elem.Parent != null)
+ throw Repo_Exception<SRootDirectory>.Factory(this, elem, Repo_Exceptions.Parent_is_null);
+
+ if (All.FirstOrDefault(e => e.Name == elem.Name) != null)
+ throw new Repo_Exception<SRootDirectory>(this, elem, "Root directory name already exist");
+
+ try
+ {
+ Directory.CreateDirectory(elem.PhysicalPath);
+ }
+ catch (Exception ex)
+ {
+ throw ex;
+ }
+ }
+
+ protected override void Validation_Update(SRootDirectory old, SRootDirectory elem)
+ {
+ if (elem.Parent != null)
+ throw new Exception();
+
+ if (old.Name != elem.Name && All.FirstOrDefault(e => e.Name == elem.Name) != null)
+ {
+ throw new Exception();
+ }
+
+ try
+ {
+ Directory.Move(old.PhysicalPath, elem.PhysicalPath);
+ }
+ catch (Exception ex)
+ {
+ throw ex;
+ }
+ }
+
+ protected override void Validation_Delete(SRootDirectory elem)
+ {
+ if (elem.Items.Count() != 0)
+ throw new Exception();
+
+ try
+ {
+ Directory.Delete(elem.PhysicalPath);
+ }
+ catch (Exception ex)
+ {
+ throw ex;
+ }
+ }
+ public void DeleteInList()
+ {
+
+ }
+
+
+ public void UploadGroups(DirectoryPermissions permissions)
+ {
+ var Group_ID = permissions.Permissions.
+ Select(e => e.GroupID);
+
+ //Select Groups from groups repo
+ IEnumerable<Group> groups = context.Groups.Where(e => Group_ID.Contains(e.ID));
+
+ foreach (var elem in permissions.Permissions)
+ elem.Group = groups.
+ FirstOrDefault(e => e.ID == elem.GroupID);
+ }
+
+ }
+}
FileServer/Model/Entities/Users/Group.cs 43(+43 -0)
diff --git a/FileServer/Model/Entities/Users/Group.cs b/FileServer/Model/Entities/Users/Group.cs
new file mode 100644
index 0000000..9b40872
--- /dev/null
+++ b/FileServer/Model/Entities/Users/Group.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.ComponentModel.DataAnnotations.Schema;
+
+using Model.Entities.Base;
+using Model.Entities.Files.FS_Entities;
+
+namespace Model.Entities.Users
+{
+
+ //public class Permission
+ //{
+ // public bool Accesse { set; get; }
+ // public bool Read { set; get; }
+ // public bool Write { set; get; }
+ //}
+
+ //public class PermissionsManager
+ //{
+ // List<Permission> Permissions = new List<Permission>();
+
+ // [NonSerialized]
+ // List<SRootDirectory> sRootDirectories = new List<SRootDirectory>();
+ // List<int> sRootDirectories_ID = new List<int>();
+
+ //}
+
+
+
+ public class Group : BaseEntity
+ {
+ public string Name { set; get; }
+ //[Column("XML_Permissions")]
+ //public string XML_Permissions { set; get; }
+
+ [InverseProperty("Groups")]
+ public virtual IEnumerable<User> Users { set; get; }
+ }
+}
diff --git a/FileServer/Model/Entities/Users/Repo/Repo_Group.cs b/FileServer/Model/Entities/Users/Repo/Repo_Group.cs
new file mode 100644
index 0000000..0e30899
--- /dev/null
+++ b/FileServer/Model/Entities/Users/Repo/Repo_Group.cs
@@ -0,0 +1,65 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Model.Entities.Base;
+using Model.UnitsOfWork;
+
+namespace Model.Entities.Users
+{
+ public enum EnumDefaultGroups
+ {
+ Администраторы,
+ Модераторы,
+ Пользователи,
+ Анонимные
+ }
+
+ public class Repo_Group : BaseRepository<Group>
+ {
+ public readonly static string[] DefaultGroupsNames = new string[]
+ {
+ EnumDefaultGroups.Администраторы.ToString(),
+ EnumDefaultGroups.Модераторы.ToString(),
+ EnumDefaultGroups.Пользователи.ToString(),
+ EnumDefaultGroups.Анонимные.ToString()
+ };
+
+ public Group GetDefaultGroup(EnumDefaultGroups en)
+ {
+ var group = All.FirstOrDefault(e => e.Name == en.ToString());
+
+ if (group == null)
+ group = Create(new Group()
+ {
+ Name = en.ToString()
+ });
+
+ return group;
+ }
+
+
+
+ public Repo_Group(Context context) : base(context) { }
+
+ protected override void Validation_Create(Group elem)
+ {
+ if (All_NoTrack.FirstOrDefault(e => e.Name == elem.Name) != null)
+ throw new Exception();
+ }
+
+ protected override void Validation_Delete(Group elem)
+ {
+ if (DefaultGroupsNames.Contains(elem.Name))
+ throw new Exception();
+ }
+
+ protected override void Validation_Update(Group old, Group elem)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
+
diff --git a/FileServer/Model/Entities/Users/Repo/Repo_User.cs b/FileServer/Model/Entities/Users/Repo/Repo_User.cs
new file mode 100644
index 0000000..fec2d2b
--- /dev/null
+++ b/FileServer/Model/Entities/Users/Repo/Repo_User.cs
@@ -0,0 +1,32 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Model.Entities.Base;
+using Model.UnitsOfWork;
+
+namespace Model.Entities.Users
+{
+ public class Repo_User : BaseRepository<User>
+ {
+ public Repo_User(Context context) : base(context) { }
+
+ protected override void Validation_Create(User elem)
+ {
+ if (All_NoTrack.FirstOrDefault(e => e.Login == elem.Login) != null)
+ throw new Exception();
+ }
+
+ protected override void Validation_Delete(User elem)
+ {
+ throw new NotImplementedException();
+ }
+
+ protected override void Validation_Update(User old, User elem)
+ {
+ throw new NotImplementedException();
+ }
+ }
+}
FileServer/Model/Entities/Users/User.cs 25(+25 -0)
diff --git a/FileServer/Model/Entities/Users/User.cs b/FileServer/Model/Entities/Users/User.cs
new file mode 100644
index 0000000..bfbe111
--- /dev/null
+++ b/FileServer/Model/Entities/Users/User.cs
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.ComponentModel.DataAnnotations.Schema;
+
+using Model.Entities.Base;
+
+namespace Model.Entities.Users
+{
+ public class User : BaseEntity
+ {
+ //[Index]
+ public string Login { set; get; }
+ public string Password { set; get; }
+ public bool IsActive { set; get; }
+
+
+ [InverseProperty("Users")]
+ public virtual IEnumerable<Group> Groups { set; get; }
+
+ }
+}
FileServer/Model/Model.csproj 83(+83 -0)
diff --git a/FileServer/Model/Model.csproj b/FileServer/Model/Model.csproj
new file mode 100644
index 0000000..cc98494
--- /dev/null
+++ b/FileServer/Model/Model.csproj
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProjectGuid>{156C9263-5079-445D-B579-3540CA1B54B1}</ProjectGuid>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Model</RootNamespace>
+ <AssemblyName>Model</AssemblyName>
+ <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ <Deterministic>true</Deterministic>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.ComponentModel.DataAnnotations" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Numerics" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Net.Http" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="Entities\Base\BaseRepository.cs" />
+ <Compile Include="Entities\Base\Base_FS_Repository.cs" />
+ <Compile Include="Entities\Base\I_Entity.cs" />
+ <Compile Include="Entities\Base\Repo_Exception.cs" />
+ <Compile Include="Entities\Files\Repo\Repo_SDirectory.cs" />
+ <Compile Include="Entities\Files\Repo\Repo_SFile.cs" />
+ <Compile Include="Entities\Files\Repo\Repo_SFileUpload.cs" />
+ <Compile Include="Entities\Files\Repo\Repo_SRootDirectory.cs" />
+ <Compile Include="Entities\Files\FS_Item.cs" />
+ <Compile Include="Entities\Base\BaseEntity.cs" />
+ <Compile Include="Entities\Files\FS_Entities\SDirectory.cs" />
+ <Compile Include="Entities\Files\FS_Entities\SFile.cs" />
+ <Compile Include="Entities\Files\FS_Entities\SFileUpload.cs" />
+ <Compile Include="Entities\Files\FS_Entities\SRootDirectory.cs" />
+ <Compile Include="Entities\Users\Group.cs" />
+ <Compile Include="Entities\Users\Repo\Repo_Group.cs" />
+ <Compile Include="Entities\Users\Repo\Repo_User.cs" />
+ <Compile Include="Entities\Users\User.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ <Compile Include="UnitsOfWork\Context.cs" />
+ <Compile Include="UnitsOfWork\UOW.cs" />
+ <Compile Include="ViewModel\Files\Directory.cs" />
+ <Compile Include="ViewModel\Files\UploadBlob.cs" />
+ </ItemGroup>
+ <ItemGroup />
+ <ItemGroup>
+ <None Include="App.config" />
+ <None Include="packages.config" />
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file
FileServer/Model/Model.csproj.user 6(+6 -0)
diff --git a/FileServer/Model/Model.csproj.user b/FileServer/Model/Model.csproj.user
new file mode 100644
index 0000000..944ec00
--- /dev/null
+++ b/FileServer/Model/Model.csproj.user
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectView>ShowAllFiles</ProjectView>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
FileServer/Model/packages.config 4(+4 -0)
diff --git a/FileServer/Model/packages.config b/FileServer/Model/packages.config
new file mode 100644
index 0000000..d8c7306
--- /dev/null
+++ b/FileServer/Model/packages.config
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="EntityFramework" version="6.2.0" targetFramework="net45" />
+</packages>
\ No newline at end of file
FileServer/Model/Properties/AssemblyInfo.cs 36(+36 -0)
diff --git a/FileServer/Model/Properties/AssemblyInfo.cs b/FileServer/Model/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..dd4b015
--- /dev/null
+++ b/FileServer/Model/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Общие сведения об этой сборке предоставляются следующим набором
+// набора атрибутов. Измените значения этих атрибутов, чтобы изменить сведения,
+// связанные со сборкой.
+[assembly: AssemblyTitle("Model")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Model")]
+[assembly: AssemblyCopyright("Copyright © 2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Установка значения False для параметра ComVisible делает типы в этой сборке невидимыми
+// для компонентов COM. Если необходимо обратиться к типу в этой сборке через
+// COM, задайте атрибуту ComVisible значение TRUE для этого типа.
+[assembly: ComVisible(false)]
+
+// Следующий GUID служит для идентификации библиотеки типов, если этот проект будет видимым для COM
+[assembly: Guid("156c9263-5079-445d-b579-3540ca1b54b1")]
+
+// Сведения о версии сборки состоят из следующих четырех значений:
+//
+// Основной номер версии
+// Дополнительный номер версии
+// Номер сборки
+// Редакция
+//
+// Можно задать все значения или принять номер сборки и номер редакции по умолчанию.
+// используя "*", как показано ниже:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
FileServer/Model/UnitsOfWork/Context.cs 58(+58 -0)
diff --git a/FileServer/Model/UnitsOfWork/Context.cs b/FileServer/Model/UnitsOfWork/Context.cs
new file mode 100644
index 0000000..7dcdc3b
--- /dev/null
+++ b/FileServer/Model/UnitsOfWork/Context.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using System.IO;
+using System.Data.Entity;
+
+using Model.Entities.Users;
+using Model.Entities.Files;
+using Model.Entities.Files.FS_Entities;
+
+namespace Model.UnitsOfWork
+{
+ public class Context :
+ DbContext
+ {
+ static string log = "Context.log";
+
+ static Context()
+ {
+ File.Delete(log);
+ }
+
+ public DbSet<User> Users { set; get; }
+ public DbSet<Group> Groups { set; get; }
+
+
+ public DbSet<FS_Item> FS_Items { set; get; }
+ public DbSet<SRootDirectory> SRootDirectories { set; get; }
+ public DbSet<SDirectory> SDirectories { set; get; }
+ public DbSet<SFile> SFiles { set; get; }
+ public DbSet<SFileUpload> SFileUploads { set; get; }
+
+
+
+ public Context(bool Clear = false) : base("DBConnection")
+ {
+ Database.Log = (s) =>
+ {
+ //using (FileStream stream = new FileStream(log, FileMode.Append))
+ //{
+ // using (StreamWriter wr = new StreamWriter(stream))
+ // {
+ // wr.WriteLine(s);
+ // }
+ //}
+ };
+
+ if (Clear && Database.Exists())
+ {
+ Database.Connection.Close();
+ Database.Delete();
+ }
+ }
+ }
+}
FileServer/Model/UnitsOfWork/UOW.cs 64(+64 -0)
diff --git a/FileServer/Model/UnitsOfWork/UOW.cs b/FileServer/Model/UnitsOfWork/UOW.cs
new file mode 100644
index 0000000..4605fb6
--- /dev/null
+++ b/FileServer/Model/UnitsOfWork/UOW.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Model.Entities.Base;
+using Model.Entities.Files;
+using Model.Entities.Files.FS_Entities;
+using Model.Entities.Files.Repo;
+using Model.Entities.Users;
+
+namespace Model.UnitsOfWork
+{
+ public class UOW
+ {
+ public readonly Context context = new Context();
+
+ public readonly Repo_SRootDirectory Repo_rootDirectory;
+ public readonly Repo_SDirectory Repo_SDirectory;
+ public readonly Repo_SFile Repo_SFile;
+ public readonly Repo_SFileUpload Repo_SFileUpload;
+
+
+ public readonly Repo_User Repo_User;
+ public readonly Repo_Group Repo_Group;
+
+ //public Base_FS_Repository<FS_Item> Repo_FS<T>() where T: FS_Item
+ //{
+ // if (typeof(T).Name == "SFile")
+ // {
+ // return Repo_SFile;
+ // }
+
+ // throw new Exception();
+ //}
+
+ public UOW()
+ {
+ Repo_rootDirectory = new Repo_SRootDirectory(context);
+ Repo_SDirectory = new Repo_SDirectory(context);
+ Repo_SFile = new Repo_SFile(context);
+ Repo_SFileUpload = new Repo_SFileUpload(context);
+
+ Repo_Group = new Repo_Group(context);
+ Repo_User = new Repo_User(context);
+
+
+ if (Repo_User.All_NoTrack.Count() == 0)
+ {
+ Repo_User.Create(new User()
+ {
+ Login = "Admin",
+ Password = "Admin",
+ IsActive = true,
+ Groups = new List<Group>()
+ {
+ Repo_Group.GetDefaultGroup(EnumDefaultGroups.Администраторы)
+ }
+ });
+ }
+ }
+ }
+}
diff --git a/FileServer/Model/ViewModel/Files/Directory.cs b/FileServer/Model/ViewModel/Files/Directory.cs
new file mode 100644
index 0000000..94b28e9
--- /dev/null
+++ b/FileServer/Model/ViewModel/Files/Directory.cs
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Model.ViewModel.Files
+{
+ class Directory
+ {
+ }
+}
diff --git a/FileServer/Model/ViewModel/Files/UploadBlob.cs b/FileServer/Model/ViewModel/Files/UploadBlob.cs
new file mode 100644
index 0000000..132b0da
--- /dev/null
+++ b/FileServer/Model/ViewModel/Files/UploadBlob.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Model.ViewModel.Files
+{
+ public class UploadBlob
+ {
+ public int ID { set; get; }
+ public string Data { set; get; }
+
+ public byte[] ToByte()
+ {
+ var base64 = Data.Substring(@"data:application/octet-stream;base64,".Length);
+ return Convert.FromBase64String(base64);
+ }
+ }
+}
FileServer/Web/App_Start/BundleConfig.cs 30(+30 -0)
diff --git a/FileServer/Web/App_Start/BundleConfig.cs b/FileServer/Web/App_Start/BundleConfig.cs
new file mode 100644
index 0000000..090356e
--- /dev/null
+++ b/FileServer/Web/App_Start/BundleConfig.cs
@@ -0,0 +1,30 @@
+using System.Web;
+using System.Web.Optimization;
+
+namespace Web
+{
+ public class BundleConfig
+ {
+ // Дополнительные сведения об объединении см. на странице https://go.microsoft.com/fwlink/?LinkId=301862
+ public static void RegisterBundles(BundleCollection bundles)
+ {
+ bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
+ "~/Scripts/jquery-{version}.js"));
+
+ bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
+ "~/Scripts/jquery.validate*"));
+
+ // Используйте версию Modernizr для разработчиков, чтобы учиться работать. Когда вы будете готовы перейти к работе,
+ // готово к выпуску, используйте средство сборки по адресу https://modernizr.com, чтобы выбрать только необходимые тесты.
+ bundles.Add(new ScriptBundle("~/bundles/modernizr").Include(
+ "~/Scripts/modernizr-*"));
+
+ bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include(
+ "~/Scripts/bootstrap.js"));
+
+ bundles.Add(new StyleBundle("~/Content/css").Include(
+ "~/Content/bootstrap.css",
+ "~/Content/site.css"));
+ }
+ }
+}
FileServer/Web/App_Start/FilterConfig.cs 13(+13 -0)
diff --git a/FileServer/Web/App_Start/FilterConfig.cs b/FileServer/Web/App_Start/FilterConfig.cs
new file mode 100644
index 0000000..892e5b6
--- /dev/null
+++ b/FileServer/Web/App_Start/FilterConfig.cs
@@ -0,0 +1,13 @@
+using System.Web;
+using System.Web.Mvc;
+
+namespace Web
+{
+ public class FilterConfig
+ {
+ public static void RegisterGlobalFilters(GlobalFilterCollection filters)
+ {
+ filters.Add(new HandleErrorAttribute());
+ }
+ }
+}
FileServer/Web/App_Start/RouteConfig.cs 23(+23 -0)
diff --git a/FileServer/Web/App_Start/RouteConfig.cs b/FileServer/Web/App_Start/RouteConfig.cs
new file mode 100644
index 0000000..e26571d
--- /dev/null
+++ b/FileServer/Web/App_Start/RouteConfig.cs
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+using System.Web.Routing;
+
+namespace Web
+{
+ public class RouteConfig
+ {
+ public static void RegisterRoutes(RouteCollection routes)
+ {
+ routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
+
+ routes.MapRoute(
+ name: "Default",
+ url: "{controller}/{action}/{id}",
+ defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
+ );
+ }
+ }
+}
FileServer/Web/App_Start/WebApiConfig.cs 21(+21 -0)
diff --git a/FileServer/Web/App_Start/WebApiConfig.cs b/FileServer/Web/App_Start/WebApiConfig.cs
new file mode 100644
index 0000000..0f8d764
--- /dev/null
+++ b/FileServer/Web/App_Start/WebApiConfig.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web.Http;
+
+namespace Web
+{
+ public static class WebApiConfig
+ {
+ public static void Register(HttpConfiguration config)
+ {
+ config.MapHttpAttributeRoutes();
+
+ config.Routes.MapHttpRoute(
+ name: "DefaultApi",
+ routeTemplate: "api/{controller}/{id}",
+ defaults: new { id = RouteParameter.Optional }
+ );
+ }
+ }
+}
diff --git a/FileServer/Web/BackgroundWorkers/GarbageUploadsWorker.cs b/FileServer/Web/BackgroundWorkers/GarbageUploadsWorker.cs
new file mode 100644
index 0000000..538b7a4
--- /dev/null
+++ b/FileServer/Web/BackgroundWorkers/GarbageUploadsWorker.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+
+using System.Threading.Tasks;
+using Quartz;
+using Quartz.Impl;
+
+using Model.UnitsOfWork;
+using BLL.Services;
+
+namespace Web.BackgroundWorkers
+{
+ public class GarbageUploadsJob : IJob
+ {
+ public async Task Execute(IJobExecutionContext context)
+ {
+ await Task.Run(() =>
+ {
+ new GarbageUploadServices(new UOW()).DeleteDead();
+ });
+ }
+ }
+
+ public class GarbageUploadsScheduler
+ {
+ public static async void Start()
+ {
+ IScheduler scheduler = await StdSchedulerFactory.GetDefaultScheduler();
+ await scheduler.Start();
+
+ IJobDetail job = JobBuilder.Create<GarbageUploadsJob>().Build();
+
+ ITrigger trigger = TriggerBuilder.Create() // создаем триггер
+ .WithIdentity("trigger1", "group1") // идентифицируем триггер с именем и группой
+ .StartNow() // запуск сразу после начала выполнения
+ .WithSimpleSchedule(x => x // настраиваем выполнение действия
+ .WithIntervalInMinutes(5) // через 5 минуту
+ .RepeatForever()) // бесконечное повторение
+ .Build(); // создаем триггер
+
+ await scheduler.ScheduleJob(job, trigger); // начинаем выполнение работы
+ }
+ }
+}
\ No newline at end of file
FileServer/Web/Controllers/API/ExplorerController.cs 182(+182 -0)
diff --git a/FileServer/Web/Controllers/API/ExplorerController.cs b/FileServer/Web/Controllers/API/ExplorerController.cs
new file mode 100644
index 0000000..ce1a786
--- /dev/null
+++ b/FileServer/Web/Controllers/API/ExplorerController.cs
@@ -0,0 +1,182 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+
+using System.IO;
+using System.Threading.Tasks;
+using System.Data.Entity;
+
+using Web.Models.Base;
+
+using Model.Entities.Files;
+using Model.Entities.Files.FS_Entities;
+using BLL.Services;
+using Model.UnitsOfWork;
+
+namespace Web.Controllers
+{
+ class ViewModelItems : BaseApiResult
+ {
+ public int ParentID { set; get; }
+ public string LogicPath { set; get; }
+ public string ParentName { set; get; }
+ public int CurrentID { set; get; }
+
+
+ public List<string> Path;
+
+ public List<ViewModelItem> items = new List<ViewModelItem>();
+
+ public ViewModelItems(bool Successe, string ResMessage)
+ : base(Successe, ResMessage, "GetDirectoryItems") { }
+
+ }
+ class ViewModelItem
+ {
+ public int ID { set; get; }
+ public string Name { set; get; }
+ public string Type { set; get; }
+ public string Size { set; get; }
+ }
+
+ public class DeleteResult : BaseApiResult
+ {
+ public DeleteResult(bool Successe, string ResMessage)
+ : base(Successe, ResMessage, "DeleteFile") { }
+ }
+
+ public class ExplorerController : BaseController
+ {
+
+
+ [HttpGet]
+ public JsonResult GetDirectoryItems(int ID)
+ {
+ if (ID == -1)
+ {
+ var data = UOW.Repo_rootDirectory.All_NoTrack_List;
+
+ var json = new ViewModelItems(true, "")
+ {
+ ParentID = -1,
+ LogicPath = @"\",
+ ParentName = "Корень",
+ CurrentID = ID
+ };
+
+ data.ForEach((e) =>
+ {
+ json.items.Add(new ViewModelItem()
+ {
+ ID = e.ID,
+ Name = e.Name,
+ Type = e.Type.ToString()
+ });
+ });
+
+ return Json(json, JsonRequestBehavior.AllowGet);
+ }
+ else
+ {
+ var data = UOW.context.FS_Items.
+ Where(e => e.ID == ID).
+ AsNoTracking().
+ Include("_Items").
+ First();
+
+ var json = new ViewModelItems(true, "")
+ {
+ ParentID = data.IsRoot ? -1 : data.Parent_ID.Value,
+ LogicPath = data.LogicPath,
+ ParentName = data.IsRoot ? "Корень" : data.Parent.Name
+ };
+
+ data.Items.ToList().ForEach((e) =>
+ {
+ if (e.Type == Enum_BaseDirectoryEntity.UploadFile)
+ return;
+
+ json.items.Add(new ViewModelItem()
+ {
+ ID = e.ID,
+ Name = e.Name,
+ Type = e.Type.ToString(),
+ Size = (e is SFile) ? e.GetSize(Enum_FileSize.MByte).ToString() : ""
+ });
+ });
+
+ return Json(json, JsonRequestBehavior.AllowGet);
+ }
+ }
+
+
+ [HttpGet]
+ public FileResult GetFile(int ID)
+ {
+ var file = UOW.Repo_SFile.All_NoTrack.FirstOrDefault(e => e.ID == ID);
+
+ return File(file.Info.Open(FileMode.Open, FileAccess.Read), "application/octet-stream", file.Name);
+ }
+
+ [HttpPost]
+ public JsonResult DeleteFile(int ID)
+ {
+ try
+ {
+ var file = UOW.Repo_SFile.All.FirstOrDefault(e => e.ID == ID);
+ UOW.Repo_SFile.Delete(file);
+ }
+ catch (Exception ex)
+ {
+ var json_err = new DeleteResult(false, ex.Message);
+
+ return Json(json_err, JsonRequestBehavior.AllowGet);
+ }
+
+ var json = new DeleteResult(true, "");
+
+ return Json(json, JsonRequestBehavior.AllowGet);
+ }
+
+ [HttpGet]
+ public async Task<JsonResult> ScanDirectory(int ID)
+ {
+ if (ID == -1)
+ {
+ var dir = UOW.Repo_rootDirectory.All_List;
+ new ConfigurationServices(UOW).
+ ReadConfiguration();
+ await new ScanServices(UOW).ScanAllDirs();
+ }
+ else
+ {
+ var dir = UOW.context.FS_Items.
+ FirstOrDefault(e => e.ID == ID);
+ await new ScanServices(UOW).
+ RecursScanDirectoryAsync((SDirectory)dir, false);
+
+
+ var items = UOW.context.FS_Items.
+ FirstOrDefault(e => e.ID == ID).Items.ToList();
+ }
+
+
+ return Json(true, JsonRequestBehavior.AllowGet);
+ }
+
+
+ public JsonResult CreateDirectory(int ParentID, string Name)
+ {
+ var parent = UOW.context.FS_Items.
+ FirstOrDefault(e => e.ID == ParentID);
+
+ UOW.Repo_SDirectory.
+ Create(new SDirectory((SDirectory)parent, Name));
+
+ return Json(true, JsonRequestBehavior.AllowGet);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/FileServer/Web/Controllers/API/UploadFilesController.cs b/FileServer/Web/Controllers/API/UploadFilesController.cs
new file mode 100644
index 0000000..c743eeb
--- /dev/null
+++ b/FileServer/Web/Controllers/API/UploadFilesController.cs
@@ -0,0 +1,104 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+
+using Model.Entities.Base;
+using Model.Entities.Files.FS_Entities;
+using Model.UnitsOfWork;
+using BLL.Services;
+
+using Model.ViewModel.Files;
+
+namespace Web.Controllers
+{
+ class UploadInfo
+ {
+ public bool State { set; get; }
+ public string Msg { set; get; }
+
+ public int ID { set; get; }
+ }
+
+
+ public class UploadFilesController : BaseController
+ {
+
+ //[HttpGet]
+ //public ActionResult UploadPage()
+ //{
+ // return View();
+ //}
+
+ [HttpPost]
+ public JsonResult StartUpload(int ParentID, string Name, long size)
+ {
+ int ID;
+
+ try
+ {
+ var parent = UOW.context.FS_Items.FirstOrDefault(e => e.ID == ParentID);
+ var proj = uploadServices.StartUpload((SDirectory)parent, Name, size);
+
+ ID = proj.ID;
+ }
+ catch (Exception ex)
+ {
+ return Json(new UploadInfo()
+ {
+ State = false,
+ Msg = ex.FullMessage()
+ });
+ }
+
+ return Json(new UploadInfo()
+ {
+ State = true,
+ ID = ID
+ });
+ }
+
+ [HttpPost]
+ public JsonResult UploadBlob()
+ {
+ UploadBlob model = new UploadBlob();
+
+ try
+ {
+ model.ID = int.Parse(Request.Form["ID"]);
+ model.Data = Request.Unvalidated.Form["chunk"];
+
+ var prog = UOW.Repo_SFileUpload.All.
+ FirstOrDefault(e => e.ID == model.ID);
+
+ uploadServices.UploadChunk(prog, model.ToByte());
+ }
+ catch (Exception ex)
+ {
+ return Json(new UploadInfo()
+ {
+ State = false,
+ Msg = ex.FullMessage()
+ });
+ }
+
+ return Json(new UploadInfo()
+ {
+ State = true
+ });
+ }
+
+ [HttpPost]
+ public JsonResult Cansel(int ID)
+ {
+ var prog = UOW.Repo_SFileUpload.All.
+ FirstOrDefault(e => e.ID == ID);
+
+ uploadServices.Cansel(prog);
+
+ return Json(true);
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/FileServer/Web/Controllers/API/UserController.cs b/FileServer/Web/Controllers/API/UserController.cs
new file mode 100644
index 0000000..92cad53
--- /dev/null
+++ b/FileServer/Web/Controllers/API/UserController.cs
@@ -0,0 +1,81 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+
+using Model.Entities.Users;
+
+namespace Web.Controllers
+{
+
+ public class AuthResult
+ {
+ public bool Successe { set; get; }
+ public string ResMsg { set; get; }
+
+ public string Token { set; get; }
+ public string UserName { set; get; }
+ }
+
+
+ public class UserController : BaseController
+ {
+
+ /// <summary>
+ /// Должен выдавать токен авторизации
+ /// </summary>
+ /// <param name="Login"></param>
+ /// <param name="Password"></param>
+ /// <returns></returns>
+ ///
+ [HttpGet]
+ public JsonResult Auth(string Login, string Password)
+ {
+ var user = UOW.Repo_User.All_NoTrack.
+ FirstOrDefault(e => e.Login == Login && e.Password == Password
+ && e.IsActive);
+
+ if (user != null)
+ {
+ return Json(new AuthResult()
+ {
+ Successe = true,
+
+ Token = user.ID.ToString(),
+ UserName = user.Login
+ }, JsonRequestBehavior.AllowGet);
+ }
+ else
+ {
+ return Json(new AuthResult()
+ {
+ Successe = false,
+ ResMsg = "Пользователь не найден или заблокирован",
+
+ Token = ""
+ }, JsonRequestBehavior.AllowGet);
+ }
+ }
+
+
+
+ public JsonResult CreateUser(string Login, string Password)
+ {
+ UOW.Repo_User.Create(new User()
+ {
+ Login = Login,
+ Password = Password,
+ IsActive = true,
+ Groups = new List<Group>()
+ {
+ UOW.Repo_Group.GetDefaultGroup(EnumDefaultGroups.Пользователи)
+ }
+ });
+
+ return Json(true, JsonRequestBehavior.AllowGet);
+ }
+
+
+ }
+}
\ No newline at end of file
diff --git a/FileServer/Web/Controllers/Base/BaseController.cs b/FileServer/Web/Controllers/Base/BaseController.cs
new file mode 100644
index 0000000..ce18922
--- /dev/null
+++ b/FileServer/Web/Controllers/Base/BaseController.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+
+using Model.UnitsOfWork;
+using BLL.Services;
+
+namespace Web.Controllers
+{
+ public abstract class BaseController : Controller
+ {
+ protected UOW UOW = new UOW();
+ protected UploadServices uploadServices;
+
+ public BaseController()
+ {
+ uploadServices = new UploadServices(UOW);
+ }
+ }
+}
\ No newline at end of file
FileServer/Web/Controllers/HomeController.cs 36(+36 -0)
diff --git a/FileServer/Web/Controllers/HomeController.cs b/FileServer/Web/Controllers/HomeController.cs
new file mode 100644
index 0000000..eea96d2
--- /dev/null
+++ b/FileServer/Web/Controllers/HomeController.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+
+namespace Web.Controllers
+{
+ public class HomeController : BaseController
+ {
+ public ActionResult Index()
+ {
+ return View();
+ }
+
+ //public ActionResult FS_Explorer()
+ //{
+ // return View();
+ //}
+
+
+ //public ActionResult About()
+ //{
+ // ViewBag.Message = "Your application description page.";
+
+ // return View();
+ //}
+
+ //public ActionResult Contact()
+ //{
+ // ViewBag.Message = "Your contact page.";
+
+ // return View();
+ //}
+ }
+}
\ No newline at end of file
FileServer/Web/favicon.ico 0(+0 -0)
diff --git a/FileServer/Web/favicon.ico b/FileServer/Web/favicon.ico
new file mode 100644
index 0000000..a3a7999
Binary files /dev/null and b/FileServer/Web/favicon.ico differ
FileServer/Web/Global.asax 1(+1 -0)
diff --git a/FileServer/Web/Global.asax b/FileServer/Web/Global.asax
new file mode 100644
index 0000000..992fba7
--- /dev/null
+++ b/FileServer/Web/Global.asax
@@ -0,0 +1 @@
+<%@ Application Codebehind="Global.asax.cs" Inherits="Web.MvcApplication" Language="C#" %>
FileServer/Web/Global.asax.cs 44(+44 -0)
diff --git a/FileServer/Web/Global.asax.cs b/FileServer/Web/Global.asax.cs
new file mode 100644
index 0000000..2d1dfa9
--- /dev/null
+++ b/FileServer/Web/Global.asax.cs
@@ -0,0 +1,44 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+using System.Web.Mvc;
+using System.Web.Optimization;
+using System.Web.Routing;
+
+using System.Threading.Tasks;
+using System.Web.Http;
+
+using Web.BackgroundWorkers;
+
+using Model.UnitsOfWork;
+using BLL.Services;
+
+
+namespace Web
+{
+ public class MvcApplication : System.Web.HttpApplication
+ {
+ protected void Application_Start()
+ {
+ AreaRegistration.RegisterAllAreas();
+ FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
+ RouteConfig.RegisterRoutes(RouteTable.Routes);
+ BundleConfig.RegisterBundles(BundleTable.Bundles);
+
+
+
+ //Очистить базу данных
+ //new Context(true);
+ var UOW = new UOW();
+ //Прочитать корневые папки
+ new ConfigurationServices(UOW).ReadConfiguration();
+ //Просканировать все папки
+ Task.WaitAll(new ScanServices(UOW).ScanAllDirs());
+
+
+ // запуск выполнения работы
+ GarbageUploadsScheduler.Start();
+ }
+ }
+}
FileServer/Web/Models/Base/BaseApiResult.cs 21(+21 -0)
diff --git a/FileServer/Web/Models/Base/BaseApiResult.cs b/FileServer/Web/Models/Base/BaseApiResult.cs
new file mode 100644
index 0000000..46f992a
--- /dev/null
+++ b/FileServer/Web/Models/Base/BaseApiResult.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Web;
+
+namespace Web.Models.Base
+{
+ public class BaseApiResult
+ {
+ public bool Successe { set; get; }
+ public string ResMessage { set; get; }
+ public string ActionName { set; get; }
+
+ public BaseApiResult(bool Successe, string ResMessage, string ActionName)
+ {
+ this.Successe = Successe;
+ this.ResMessage = ResMessage;
+ this.ActionName = ActionName;
+ }
+ }
+}
\ No newline at end of file
FileServer/Web/packages.config 30(+30 -0)
diff --git a/FileServer/Web/packages.config b/FileServer/Web/packages.config
new file mode 100644
index 0000000..7a81a10
--- /dev/null
+++ b/FileServer/Web/packages.config
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<packages>
+ <package id="Antlr" version="3.5.0.2" targetFramework="net45" />
+ <package id="bootstrap" version="4.3.1" targetFramework="net452" />
+ <package id="EntityFramework" version="6.2.0" targetFramework="net45" />
+ <package id="jQuery" version="3.4.1" targetFramework="net452" />
+ <package id="jQuery.Validation" version="1.17.0" targetFramework="net45" />
+ <package id="Microsoft.AspNet.Mvc" version="5.2.7" targetFramework="net452" />
+ <package id="Microsoft.AspNet.Mvc.ru" version="5.2.7" targetFramework="net452" />
+ <package id="Microsoft.AspNet.Razor" version="3.2.7" targetFramework="net452" />
+ <package id="Microsoft.AspNet.Razor.ru" version="3.2.7" targetFramework="net452" />
+ <package id="Microsoft.AspNet.TelemetryCorrelation" version="1.0.5" targetFramework="net452" />
+ <package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net45" />
+ <package id="Microsoft.AspNet.Web.Optimization.ru" version="1.1.3" targetFramework="net45" />
+ <package id="Microsoft.AspNet.WebApi" version="5.2.7" targetFramework="net452" />
+ <package id="Microsoft.AspNet.WebApi.Client" version="5.2.7" targetFramework="net452" />
+ <package id="Microsoft.AspNet.WebApi.Core" version="5.2.7" targetFramework="net452" />
+ <package id="Microsoft.AspNet.WebApi.WebHost" version="5.2.7" targetFramework="net452" />
+ <package id="Microsoft.AspNet.WebPages" version="3.2.7" targetFramework="net452" />
+ <package id="Microsoft.AspNet.WebPages.ru" version="3.2.7" targetFramework="net452" />
+ <package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="2.0.1" targetFramework="net452" />
+ <package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.11" targetFramework="net452" />
+ <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />
+ <package id="Modernizr" version="2.8.3" targetFramework="net45" />
+ <package id="Newtonsoft.Json" version="12.0.2" targetFramework="net452" />
+ <package id="popper.js" version="1.14.3" targetFramework="net452" />
+ <package id="Quartz" version="3.0.7" targetFramework="net452" />
+ <package id="System.Diagnostics.DiagnosticSource" version="4.5.1" targetFramework="net452" />
+ <package id="WebGrease" version="1.6.0" targetFramework="net45" />
+</packages>
\ No newline at end of file
FileServer/Web/Properties/AssemblyInfo.cs 35(+35 -0)
diff --git a/FileServer/Web/Properties/AssemblyInfo.cs b/FileServer/Web/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000..babe6e4
--- /dev/null
+++ b/FileServer/Web/Properties/AssemblyInfo.cs
@@ -0,0 +1,35 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// Управление общими сведениями о сборке осуществляется следующим образом
+// набора атрибутов. Измените значения этих атрибутов для изменения сведений,
+// связанных с этой сборкой.
+[assembly: AssemblyTitle("Web")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("Web")]
+[assembly: AssemblyCopyright("© , 2019")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Установка значения False в параметре ComVisible делает типы в этой сборке невидимыми
+// для компонентов COM. Если требуется обратиться к типу в этой сборке через
+// COM, задайте атрибуту ComVisible значение true для требуемого типа.
+[assembly: ComVisible(false)]
+
+// Следующий GUID служит для ID библиотеки типов typelib, если этот проект видим для COM
+[assembly: Guid("85db6c63-d4d7-4697-bd5d-8453f6e1641a")]
+
+// Сведения о версии сборки состоят из указанных ниже четырех значений:
+//
+// основной номер версии;
+// Дополнительный номер версии
+// номер сборки;
+// редакция.
+//
+// Можно задать все значения или принять номер редакции и номер сборки по умолчанию,
+// используя "*", как показано ниже:
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/FileServer/Web/Properties/PublishProfiles/FolderProfile.pubxml b/FileServer/Web/Properties/PublishProfiles/FolderProfile.pubxml
new file mode 100644
index 0000000..634af90
--- /dev/null
+++ b/FileServer/Web/Properties/PublishProfiles/FolderProfile.pubxml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Этот файл используется процессом публикации или упаковки вашего веб-проекта. Можно настроить поведение этого процесса,
+изменив этот файл MSBuild. Подробности см. на странице https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <WebPublishMethod>FileSystem</WebPublishMethod>
+ <PublishProvider>FileSystem</PublishProvider>
+ <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>
+ <LastUsedPlatform>Any CPU</LastUsedPlatform>
+ <SiteUrlToLaunchAfterPublish />
+ <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>
+ <ExcludeApp_Data>False</ExcludeApp_Data>
+ <publishUrl>bin\Release\Publish</publishUrl>
+ <DeleteExistingFiles>True</DeleteExistingFiles>
+ </PropertyGroup>
+</Project>
\ No newline at end of file
diff --git a/FileServer/Web/Properties/PublishProfiles/FolderProfile.pubxml.user b/FileServer/Web/Properties/PublishProfiles/FolderProfile.pubxml.user
new file mode 100644
index 0000000..e0dda47
--- /dev/null
+++ b/FileServer/Web/Properties/PublishProfiles/FolderProfile.pubxml.user
@@ -0,0 +1,853 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Этот файл используется процессом публикации или упаковки вашего веб-проекта. Можно настроить поведение этого процесса,
+изменив этот файл MSBuild. Подробности см. на странице https://go.microsoft.com/fwlink/?LinkID=208121.
+-->
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <TimeStampOfAssociatedLegacyPublishXmlFile />
+ <_PublishTargetUrl>C:\Users\cccc1808\source\repos\FileServer\Web\bin\Release\Publish</_PublishTargetUrl>
+ </PropertyGroup>
+ <ItemGroup>
+ <File Include="bin/Antlr3.Runtime.dll">
+ <publishTime>09/10/2013 17:29:20</publishTime>
+ </File>
+ <File Include="bin/Antlr3.Runtime.pdb">
+ <publishTime>09/10/2013 17:29:20</publishTime>
+ </File>
+ <File Include="bin/BLL.dll">
+ <publishTime>07/18/2019 03:22:57</publishTime>
+ </File>
+ <File Include="bin/BLL.dll.config">
+ <publishTime>07/16/2019 02:33:46</publishTime>
+ </File>
+ <File Include="bin/BLL.pdb">
+ <publishTime>07/18/2019 03:22:57</publishTime>
+ </File>
+ <File Include="bin/EntityFramework.dll">
+ <publishTime>10/23/2017 13:15:18</publishTime>
+ </File>
+ <File Include="bin/EntityFramework.SqlServer.dll">
+ <publishTime>10/23/2017 13:15:20</publishTime>
+ </File>
+ <File Include="bin/Microsoft.AspNet.TelemetryCorrelation.dll">
+ <publishTime>11/21/2018 01:48:22</publishTime>
+ </File>
+ <File Include="bin/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll">
+ <publishTime>09/05/2018 16:10:50</publishTime>
+ </File>
+ <File Include="bin/Microsoft.Web.Infrastructure.dll">
+ <publishTime>07/25/2012 12:48:56</publishTime>
+ </File>
+ <File Include="bin/Model.dll">
+ <publishTime>07/18/2019 03:22:57</publishTime>
+ </File>
+ <File Include="bin/Model.dll.config">
+ <publishTime>07/12/2019 18:37:12</publishTime>
+ </File>
+ <File Include="bin/Model.pdb">
+ <publishTime>07/18/2019 03:22:57</publishTime>
+ </File>
+ <File Include="bin/Newtonsoft.Json.dll">
+ <publishTime>04/22/2019 01:06:16</publishTime>
+ </File>
+ <File Include="bin/Quartz.dll">
+ <publishTime>10/07/2018 12:27:38</publishTime>
+ </File>
+ <File Include="bin/Quartz.pdb">
+ <publishTime>10/07/2018 12:27:38</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Antlr3.Runtime.dll">
+ <publishTime>09/10/2013 17:29:20</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Antlr3.Runtime.pdb">
+ <publishTime>09/10/2013 17:29:20</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/BLL.dll">
+ <publishTime>07/18/2019 03:22:57</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/BLL.dll.config">
+ <publishTime>07/16/2019 02:33:46</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/BLL.pdb">
+ <publishTime>07/18/2019 03:22:57</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/EntityFramework.dll">
+ <publishTime>10/23/2017 13:15:18</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/EntityFramework.SqlServer.dll">
+ <publishTime>10/23/2017 13:15:20</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Microsoft.AspNet.TelemetryCorrelation.dll">
+ <publishTime>11/21/2018 01:48:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll">
+ <publishTime>09/05/2018 16:10:50</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Microsoft.Web.Infrastructure.dll">
+ <publishTime>07/25/2012 12:48:56</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Model.dll">
+ <publishTime>07/18/2019 03:22:57</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Model.dll.config">
+ <publishTime>07/12/2019 18:37:12</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Model.pdb">
+ <publishTime>07/18/2019 03:22:57</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Newtonsoft.Json.dll">
+ <publishTime>04/22/2019 01:06:16</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Quartz.dll">
+ <publishTime>10/07/2018 12:27:38</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Quartz.pdb">
+ <publishTime>10/07/2018 12:27:38</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/csc.exe">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/csc.exe.config">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/csc.rsp">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/csi.exe">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/csi.rsp">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/Microsoft.Build.Tasks.CodeAnalysis.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/Microsoft.CodeAnalysis.CSharp.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/Microsoft.CodeAnalysis.CSharp.Scripting.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/Microsoft.CodeAnalysis.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/Microsoft.CodeAnalysis.Scripting.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/Microsoft.CodeAnalysis.VisualBasic.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/Microsoft.CSharp.Core.targets">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/Microsoft.DiaSymReader.Native.amd64.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/Microsoft.DiaSymReader.Native.x86.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/Microsoft.VisualBasic.Core.targets">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/System.AppContext.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/System.Collections.Immutable.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/System.Diagnostics.StackTrace.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/System.IO.FileSystem.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/System.IO.FileSystem.Primitives.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/System.Reflection.Metadata.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/vbc.exe">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/vbc.exe.config">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/vbc.rsp">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/VBCSCompiler.exe">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/roslyn/VBCSCompiler.exe.config">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/ru/System.Web.Helpers.resources.dll">
+ <publishTime>11/28/2018 13:04:46</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/ru/System.Web.Mvc.resources.dll">
+ <publishTime>11/28/2018 13:00:10</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/ru/System.Web.Optimization.resources.dll">
+ <publishTime>02/11/2014 15:28:42</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/ru/System.Web.Razor.resources.dll">
+ <publishTime>11/28/2018 13:00:32</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/ru/System.Web.WebPages.Deployment.resources.dll">
+ <publishTime>11/28/2018 13:04:46</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/ru/System.Web.WebPages.Razor.resources.dll">
+ <publishTime>11/28/2018 13:04:46</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/ru/System.Web.WebPages.resources.dll">
+ <publishTime>11/28/2018 13:04:46</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/System.Diagnostics.DiagnosticSource.dll">
+ <publishTime>09/18/2018 19:38:16</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/System.Net.Http.Formatting.dll">
+ <publishTime>11/28/2018 13:00:36</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/System.Web.Helpers.dll">
+ <publishTime>11/28/2018 13:04:24</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/System.Web.Http.dll">
+ <publishTime>01/28/2015 04:02:54</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/System.Web.Http.WebHost.dll">
+ <publishTime>11/28/2018 13:02:56</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/System.Web.Mvc.dll">
+ <publishTime>11/28/2018 12:59:46</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/System.Web.Optimization.dll">
+ <publishTime>02/11/2014 16:26:04</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/System.Web.Razor.dll">
+ <publishTime>11/28/2018 13:00:12</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/System.Web.WebPages.Deployment.dll">
+ <publishTime>11/28/2018 13:04:24</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/System.Web.WebPages.dll">
+ <publishTime>11/28/2018 13:04:24</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/System.Web.WebPages.Razor.dll">
+ <publishTime>11/28/2018 13:04:24</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Web.dll">
+ <publishTime>07/18/2019 03:23:01</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/Web.pdb">
+ <publishTime>07/18/2019 03:23:01</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/bin/WebGrease.dll">
+ <publishTime>01/23/2014 14:57:34</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Content/bootstrap-theme.css">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Content/bootstrap-theme.css.map">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Content/bootstrap-theme.min.css">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Content/bootstrap-theme.min.css.map">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Content/bootstrap.css">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Content/bootstrap.css.map">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Content/bootstrap.min.css">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Content/bootstrap.min.css.map">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Content/Site.css">
+ <publishTime>07/13/2019 20:52:13</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/favicon.ico">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/fonts/glyphicons-halflings-regular.eot">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/fonts/glyphicons-halflings-regular.svg">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/fonts/glyphicons-halflings-regular.ttf">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/fonts/glyphicons-halflings-regular.woff">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/fonts/glyphicons-halflings-regular.woff2">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Global.asax">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/bootstrap.js">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/bootstrap.min.js">
+ <publishTime>07/17/2019 23:50:56</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/jquery-3.3.1.js">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/jquery-3.3.1.min.js">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/jquery-3.3.1.min.map">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/jquery-3.3.1.slim.js">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/jquery-3.3.1.slim.min.js">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/jquery-3.3.1.slim.min.map">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/jquery.validate.js">
+ <publishTime>07/13/2019 20:52:26</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/jquery.validate.min.js">
+ <publishTime>07/13/2019 20:52:26</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/jquery.validate.unobtrusive.js">
+ <publishTime>07/17/2019 23:50:44</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/jquery.validate.unobtrusive.min.js">
+ <publishTime>07/17/2019 23:50:44</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/Manager/FileExplorerManager.js">
+ <publishTime>07/16/2019 04:48:48</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/Manager/UploadManager.js">
+ <publishTime>07/16/2019 13:31:11</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/Manager/UserManager.js">
+ <publishTime>07/16/2019 04:48:25</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/modernizr-2.8.3.js">
+ <publishTime>07/13/2019 20:52:24</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/React/App.jsx">
+ <publishTime>07/18/2019 03:08:14</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/React/ExplorerControl.jsx">
+ <publishTime>07/18/2019 03:21:49</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/React/FileExplorer.jsx">
+ <publishTime>07/17/2019 01:17:38</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/React/FileExplorerRow.jsx">
+ <publishTime>07/17/2019 23:16:46</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/React/RouteSystem.jsx">
+ <publishTime>07/17/2019 01:11:08</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/React/Uploader.jsx">
+ <publishTime>07/17/2019 00:43:36</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/React/UserControl.jsx">
+ <publishTime>07/18/2019 02:56:42</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/SiteScripts/Downloader.js">
+ <publishTime>07/15/2019 20:59:15</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Scripts/Tools/Sort.js">
+ <publishTime>07/16/2019 14:25:53</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Views/App/Index.cshtml">
+ <publishTime>07/15/2019 20:44:17</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Views/Home/About.cshtml">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Views/Home/Contact.cshtml">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Views/Home/FS_Explorer.cshtml">
+ <publishTime>07/15/2019 03:38:23</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Views/Home/Index.cshtml">
+ <publishTime>07/18/2019 03:08:06</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Views/Shared/Error.cshtml">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Views/Shared/_Layout.cshtml">
+ <publishTime>07/18/2019 00:25:39</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Views/UploadFiles/UploadPage.cshtml">
+ <publishTime>07/14/2019 02:02:24</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Views/Web.config">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Views/_ViewStart.cshtml">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="bin/Release/Publish/Web.config">
+ <publishTime>07/18/2019 03:23:02</publishTime>
+ </File>
+ <File Include="bin/roslyn/csc.exe">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/csc.exe.config">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/csc.rsp">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/csi.exe">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/csi.rsp">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/Microsoft.Build.Tasks.CodeAnalysis.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/Microsoft.CodeAnalysis.CSharp.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/Microsoft.CodeAnalysis.CSharp.Scripting.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/Microsoft.CodeAnalysis.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/Microsoft.CodeAnalysis.Scripting.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/Microsoft.CodeAnalysis.VisualBasic.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/Microsoft.CSharp.Core.targets">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/Microsoft.DiaSymReader.Native.amd64.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/Microsoft.DiaSymReader.Native.x86.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/Microsoft.VisualBasic.Core.targets">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/System.AppContext.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/System.Collections.Immutable.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/System.Diagnostics.StackTrace.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/System.IO.FileSystem.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/System.IO.FileSystem.Primitives.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/System.Reflection.Metadata.dll">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/vbc.exe">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/vbc.exe.config">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/vbc.rsp">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/VBCSCompiler.exe">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/roslyn/VBCSCompiler.exe.config">
+ <publishTime>05/24/2018 14:38:22</publishTime>
+ </File>
+ <File Include="bin/ru/System.Web.Helpers.resources.dll">
+ <publishTime>11/28/2018 13:04:46</publishTime>
+ </File>
+ <File Include="bin/ru/System.Web.Mvc.resources.dll">
+ <publishTime>11/28/2018 13:00:10</publishTime>
+ </File>
+ <File Include="bin/ru/System.Web.Optimization.resources.dll">
+ <publishTime>02/11/2014 15:28:42</publishTime>
+ </File>
+ <File Include="bin/ru/System.Web.Razor.resources.dll">
+ <publishTime>11/28/2018 13:00:32</publishTime>
+ </File>
+ <File Include="bin/ru/System.Web.WebPages.Deployment.resources.dll">
+ <publishTime>11/28/2018 13:04:46</publishTime>
+ </File>
+ <File Include="bin/ru/System.Web.WebPages.Razor.resources.dll">
+ <publishTime>11/28/2018 13:04:46</publishTime>
+ </File>
+ <File Include="bin/ru/System.Web.WebPages.resources.dll">
+ <publishTime>11/28/2018 13:04:46</publishTime>
+ </File>
+ <File Include="bin/System.Diagnostics.DiagnosticSource.dll">
+ <publishTime>09/18/2018 19:38:16</publishTime>
+ </File>
+ <File Include="bin/System.Net.Http.Formatting.dll">
+ <publishTime>11/28/2018 13:00:36</publishTime>
+ </File>
+ <File Include="bin/System.Web.Helpers.dll">
+ <publishTime>11/28/2018 13:04:24</publishTime>
+ </File>
+ <File Include="bin/System.Web.Http.dll">
+ <publishTime>11/28/2018 13:01:00</publishTime>
+ </File>
+ <File Include="bin/System.Web.Http.WebHost.dll">
+ <publishTime>11/28/2018 13:02:56</publishTime>
+ </File>
+ <File Include="bin/System.Web.Mvc.dll">
+ <publishTime>11/28/2018 12:59:46</publishTime>
+ </File>
+ <File Include="bin/System.Web.Optimization.dll">
+ <publishTime>02/11/2014 16:26:04</publishTime>
+ </File>
+ <File Include="bin/System.Web.Razor.dll">
+ <publishTime>11/28/2018 13:00:12</publishTime>
+ </File>
+ <File Include="bin/System.Web.WebPages.Deployment.dll">
+ <publishTime>11/28/2018 13:04:24</publishTime>
+ </File>
+ <File Include="bin/System.Web.WebPages.dll">
+ <publishTime>11/28/2018 13:04:24</publishTime>
+ </File>
+ <File Include="bin/System.Web.WebPages.Razor.dll">
+ <publishTime>11/28/2018 13:04:24</publishTime>
+ </File>
+ <File Include="bin/Web.dll">
+ <publishTime>07/18/2019 03:49:43</publishTime>
+ </File>
+ <File Include="bin/Web.pdb">
+ <publishTime>07/18/2019 03:49:43</publishTime>
+ </File>
+ <File Include="bin/WebGrease.dll">
+ <publishTime>01/23/2014 14:57:34</publishTime>
+ </File>
+ <File Include="Content/bootstrap-grid.css">
+ <publishTime>07/17/2019 23:50:58</publishTime>
+ </File>
+ <File Include="Content/bootstrap-grid.css.map">
+ <publishTime>07/17/2019 23:50:58</publishTime>
+ </File>
+ <File Include="Content/bootstrap-grid.min.css">
+ <publishTime>07/17/2019 23:50:58</publishTime>
+ </File>
+ <File Include="Content/bootstrap-grid.min.css.map">
+ <publishTime>07/17/2019 23:50:58</publishTime>
+ </File>
+ <File Include="Content/bootstrap-reboot.css">
+ <publishTime>07/17/2019 23:50:58</publishTime>
+ </File>
+ <File Include="Content/bootstrap-reboot.css.map">
+ <publishTime>07/17/2019 23:50:58</publishTime>
+ </File>
+ <File Include="Content/bootstrap-reboot.min.css">
+ <publishTime>07/17/2019 23:50:58</publishTime>
+ </File>
+ <File Include="Content/bootstrap-reboot.min.css.map">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="Content/bootstrap-theme.css">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="Content/bootstrap-theme.css.map">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="Content/bootstrap-theme.min.css">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="Content/bootstrap-theme.min.css.map">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="Content/bootstrap.css">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="Content/bootstrap.css.map">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="Content/bootstrap.min.css">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="Content/bootstrap.min.css.map">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="Content/Site.css">
+ <publishTime>07/13/2019 20:52:13</publishTime>
+ </File>
+ <File Include="favicon.ico">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="fonts/glyphicons-halflings-regular.eot">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="fonts/glyphicons-halflings-regular.svg">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="fonts/glyphicons-halflings-regular.ttf">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="fonts/glyphicons-halflings-regular.woff">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="fonts/glyphicons-halflings-regular.woff2">
+ <publishTime>07/13/2019 20:52:19</publishTime>
+ </File>
+ <File Include="Global.asax">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="Scripts/bootstrap.bundle.js">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="Scripts/bootstrap.bundle.js.map">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="Scripts/bootstrap.bundle.min.js">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="Scripts/bootstrap.bundle.min.js.map">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="Scripts/bootstrap.js">
+ <publishTime>07/17/2019 23:50:57</publishTime>
+ </File>
+ <File Include="Scripts/bootstrap.js.map">
+ <publishTime>07/17/2019 23:50:56</publishTime>
+ </File>
+ <File Include="Scripts/bootstrap.min.js">
+ <publishTime>07/17/2019 23:50:56</publishTime>
+ </File>
+ <File Include="Scripts/bootstrap.min.js.map">
+ <publishTime>07/17/2019 23:50:56</publishTime>
+ </File>
+ <File Include="Scripts/esm/popper-utils.js">
+ <publishTime>07/17/2019 23:51:36</publishTime>
+ </File>
+ <File Include="Scripts/esm/popper-utils.js.map">
+ <publishTime>07/17/2019 23:51:36</publishTime>
+ </File>
+ <File Include="Scripts/esm/popper-utils.min.js">
+ <publishTime>07/17/2019 23:51:36</publishTime>
+ </File>
+ <File Include="Scripts/esm/popper-utils.min.js.map">
+ <publishTime>07/17/2019 23:51:36</publishTime>
+ </File>
+ <File Include="Scripts/esm/popper.js">
+ <publishTime>07/17/2019 23:51:36</publishTime>
+ </File>
+ <File Include="Scripts/esm/popper.js.map">
+ <publishTime>07/17/2019 23:51:36</publishTime>
+ </File>
+ <File Include="Scripts/esm/popper.min.js">
+ <publishTime>07/17/2019 23:51:36</publishTime>
+ </File>
+ <File Include="Scripts/esm/popper.min.js.map">
+ <publishTime>07/17/2019 23:51:36</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.3.1.js">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.3.1.min.js">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.3.1.min.map">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.3.1.slim.js">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.3.1.slim.min.js">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.3.1.slim.min.map">
+ <publishTime>07/13/2019 20:52:20</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.4.1.js">
+ <publishTime>07/17/2019 23:50:39</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.4.1.min.js">
+ <publishTime>07/17/2019 23:50:39</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.4.1.min.map">
+ <publishTime>07/17/2019 23:50:39</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.4.1.slim.js">
+ <publishTime>07/17/2019 23:50:39</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.4.1.slim.min.js">
+ <publishTime>07/17/2019 23:50:39</publishTime>
+ </File>
+ <File Include="Scripts/jquery-3.4.1.slim.min.map">
+ <publishTime>07/17/2019 23:50:38</publishTime>
+ </File>
+ <File Include="Scripts/jquery.validate.js">
+ <publishTime>07/13/2019 20:52:26</publishTime>
+ </File>
+ <File Include="Scripts/jquery.validate.min.js">
+ <publishTime>07/13/2019 20:52:26</publishTime>
+ </File>
+ <File Include="Scripts/jquery.validate.unobtrusive.js">
+ <publishTime>07/17/2019 23:50:44</publishTime>
+ </File>
+ <File Include="Scripts/jquery.validate.unobtrusive.min.js">
+ <publishTime>07/17/2019 23:50:44</publishTime>
+ </File>
+ <File Include="Scripts/Manager/FileExplorerManager.js">
+ <publishTime>07/16/2019 04:48:48</publishTime>
+ </File>
+ <File Include="Scripts/Manager/UploadManager.js">
+ <publishTime>07/16/2019 13:31:11</publishTime>
+ </File>
+ <File Include="Scripts/Manager/UserManager.js">
+ <publishTime>07/16/2019 04:48:25</publishTime>
+ </File>
+ <File Include="Scripts/modernizr-2.8.3.js">
+ <publishTime>07/13/2019 20:52:24</publishTime>
+ </File>
+ <File Include="Scripts/popper-utils.js">
+ <publishTime>07/17/2019 23:51:35</publishTime>
+ </File>
+ <File Include="Scripts/popper-utils.js.map">
+ <publishTime>07/17/2019 23:51:35</publishTime>
+ </File>
+ <File Include="Scripts/popper-utils.min.js">
+ <publishTime>07/17/2019 23:51:35</publishTime>
+ </File>
+ <File Include="Scripts/popper-utils.min.js.map">
+ <publishTime>07/17/2019 23:51:35</publishTime>
+ </File>
+ <File Include="Scripts/popper.js">
+ <publishTime>07/17/2019 23:51:35</publishTime>
+ </File>
+ <File Include="Scripts/popper.js.map">
+ <publishTime>07/17/2019 23:51:35</publishTime>
+ </File>
+ <File Include="Scripts/popper.min.js">
+ <publishTime>07/17/2019 23:51:35</publishTime>
+ </File>
+ <File Include="Scripts/popper.min.js.map">
+ <publishTime>07/17/2019 23:51:35</publishTime>
+ </File>
+ <File Include="Scripts/React/App.jsx">
+ <publishTime>07/18/2019 03:08:14</publishTime>
+ </File>
+ <File Include="Scripts/React/ExplorerControl.jsx">
+ <publishTime>07/18/2019 03:21:49</publishTime>
+ </File>
+ <File Include="Scripts/React/FileExplorer.jsx">
+ <publishTime>07/17/2019 01:17:38</publishTime>
+ </File>
+ <File Include="Scripts/React/FileExplorerControl.jsx">
+ <publishTime>07/18/2019 03:00:04</publishTime>
+ </File>
+ <File Include="Scripts/React/FileExplorerRow.jsx">
+ <publishTime>07/17/2019 23:16:46</publishTime>
+ </File>
+ <File Include="Scripts/React/RouteSystem.jsx">
+ <publishTime>07/17/2019 01:11:08</publishTime>
+ </File>
+ <File Include="Scripts/React/Uploader.jsx">
+ <publishTime>07/17/2019 00:43:36</publishTime>
+ </File>
+ <File Include="Scripts/React/UploaderControl.jsx">
+ <publishTime>07/18/2019 03:01:32</publishTime>
+ </File>
+ <File Include="Scripts/React/UserControl.jsx">
+ <publishTime>07/18/2019 02:56:42</publishTime>
+ </File>
+ <File Include="Scripts/README.md">
+ <publishTime>07/17/2019 23:51:35</publishTime>
+ </File>
+ <File Include="Scripts/Services/FileExplorerServices.js">
+ <publishTime>07/18/2019 03:18:34</publishTime>
+ </File>
+ <File Include="Scripts/Services/UploadServices.js">
+ <publishTime>07/18/2019 02:33:28</publishTime>
+ </File>
+ <File Include="Scripts/Services/UserServices.js">
+ <publishTime>07/18/2019 02:56:02</publishTime>
+ </File>
+ <File Include="Scripts/SiteScripts/Downloader.js">
+ <publishTime>07/15/2019 20:59:15</publishTime>
+ </File>
+ <File Include="Scripts/Tools/Sort.js">
+ <publishTime>07/16/2019 14:25:53</publishTime>
+ </File>
+ <File Include="Scripts/umd/popper-utils.js">
+ <publishTime>07/17/2019 23:51:35</publishTime>
+ </File>
+ <File Include="Scripts/umd/popper-utils.js.map">
+ <publishTime>07/17/2019 23:51:34</publishTime>
+ </File>
+ <File Include="Scripts/umd/popper-utils.min.js">
+ <publishTime>07/17/2019 23:51:34</publishTime>
+ </File>
+ <File Include="Scripts/umd/popper-utils.min.js.map">
+ <publishTime>07/17/2019 23:51:34</publishTime>
+ </File>
+ <File Include="Scripts/umd/popper.js">
+ <publishTime>07/17/2019 23:51:34</publishTime>
+ </File>
+ <File Include="Scripts/umd/popper.js.map">
+ <publishTime>07/17/2019 23:51:34</publishTime>
+ </File>
+ <File Include="Scripts/umd/popper.min.js">
+ <publishTime>07/17/2019 23:51:34</publishTime>
+ </File>
+ <File Include="Scripts/umd/popper.min.js.map">
+ <publishTime>07/17/2019 23:51:34</publishTime>
+ </File>
+ <File Include="Views/App/Index.cshtml">
+ <publishTime>07/15/2019 20:44:17</publishTime>
+ </File>
+ <File Include="Views/Home/About.cshtml">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="Views/Home/Contact.cshtml">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="Views/Home/FS_Explorer.cshtml">
+ <publishTime>07/15/2019 03:38:23</publishTime>
+ </File>
+ <File Include="Views/Home/Index.cshtml">
+ <publishTime>07/18/2019 03:08:06</publishTime>
+ </File>
+ <File Include="Views/Shared/Error.cshtml">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="Views/Shared/_Layout.cshtml">
+ <publishTime>07/18/2019 00:25:39</publishTime>
+ </File>
+ <File Include="Views/UploadFiles/UploadPage.cshtml">
+ <publishTime>07/14/2019 02:02:24</publishTime>
+ </File>
+ <File Include="Views/Web.config">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="Views/_ViewStart.cshtml">
+ <publishTime>07/13/2019 20:52:14</publishTime>
+ </File>
+ <File Include="Web.config">
+ <publishTime>07/18/2019 03:23:02</publishTime>
+ </File>
+ </ItemGroup>
+</Project>
\ No newline at end of file
FileServer/Web/Scripts/React/App.jsx 81(+81 -0)
diff --git a/FileServer/Web/Scripts/React/App.jsx b/FileServer/Web/Scripts/React/App.jsx
new file mode 100644
index 0000000..0a69099
--- /dev/null
+++ b/FileServer/Web/Scripts/React/App.jsx
@@ -0,0 +1,81 @@
+
+class App extends React.Component {
+
+ constructor(props) {
+ super(props);
+ console.log('App start');
+
+ //this.state = { counter: 0 };
+
+ this.OnItemsChange = this.OnItemsChange.bind(this);
+
+ this.SetID = this.SetID.bind(this);
+ this.GetID = this.GetID.bind(this);
+
+ //Получить ID из url
+ var Url_ID = new URL(window.location.href).
+ searchParams.get("ID");
+
+ if (Url_ID != null)
+ this.SetID(Url_ID);
+ //if (this.props.match != undefined
+ // && this.props.match.params != undefined
+ // && this.props.match.params.ID != undefined)
+ // this.SetID(this.props.match.params.ID);
+ //Получить id от родительского компонента
+ else if (this.props.ID != undefined)
+ this.SetID(this.props.ID);
+ }
+
+ OnItemsChange() {
+ this.refs.FileExplorerControl.
+ LoadDirectory();
+ }
+
+ SetID(val)
+ {
+ this.CurrentID = val;
+ console.log(this.CurrentID);
+ }
+
+ GetID()
+ {
+ return this.CurrentID;
+ }
+
+
+ render() {
+ return (
+ <div>
+
+ <UserControl ref="UserControl"
+ ParentComponent={this}
+ />
+
+ <hr />
+ <FileExplorerControl ref="FileExplorerControl"
+ ParentComponent={this}
+ GetID={this.GetID} SetID={this.SetID}
+ OnItemsChange={this.OnItemsChange}
+ OnItemsChangesObservers_Register={this.OnItemsChangesObservers_Register}
+ />
+ <hr />
+ <ExplorerActionsControl ref="ExplorerActionsControl"
+ ParentComponent={this}
+ />
+ <hr />
+ <UploaderControl ref="UploaderControl"
+ ParentComponent={this}
+ GetID={this.GetID}
+ OnItemsChange={this.OnItemsChange}
+ />
+ <hr />
+ <BootstrapControl
+ />
+ <hr />
+
+ </div>
+ );
+ }
+}
+
diff --git a/FileServer/Web/Scripts/React/BootstrapControl.jsx b/FileServer/Web/Scripts/React/BootstrapControl.jsx
new file mode 100644
index 0000000..a97f515
--- /dev/null
+++ b/FileServer/Web/Scripts/React/BootstrapControl.jsx
@@ -0,0 +1,28 @@
+
+class BootstrapControl extends React.Component {
+
+ constructor(props) {
+ super(props);
+ console.log('BootstrapControl start');
+ }
+
+
+ render() {
+
+ return (
+ <div>
+ <ButtonToolbar>
+ <Button variant="outline-primary">Primary</Button>
+ <Button variant="outline-secondary">Secondary</Button>
+ <Button variant="outline-success">Success</Button>
+ <Button variant="outline-warning">Warning</Button>
+ <Button variant="outline-danger">Danger</Button>
+ <Button variant="outline-info">Info</Button>
+ <Button variant="outline-light">Light</Button>
+ <Button variant="outline-dark">Dark</Button>
+ </ButtonToolbar>
+ </div>
+ );
+
+ }
+}
diff --git a/FileServer/Web/Scripts/React/ExplorerActionsControl.jsx b/FileServer/Web/Scripts/React/ExplorerActionsControl.jsx
new file mode 100644
index 0000000..bb0244a
--- /dev/null
+++ b/FileServer/Web/Scripts/React/ExplorerActionsControl.jsx
@@ -0,0 +1,124 @@
+
+class ExplorerActionsControl extends React.Component {
+
+ constructor(props) {
+ super(props);
+ console.log('ExplorerControl start');
+
+ this.state = { ResultMsg: "" }
+ this.fileExplorerServices = new FileExplorerServices();
+
+ this.OnDownloadClick = this.OnDownloadClick.bind(this);
+ this.OnDeleteClick = this.OnDeleteClick.bind(this);
+ this.OnCreateDirectoryClick = this.OnCreateDirectoryClick.bind(this);
+ }
+
+
+ OnDownloadClick(sender) {
+
+ let selected = this.props.ParentComponent.refs.
+ FileExplorerControl.GetSelectedID();
+
+ selected.map((e) => {
+ console.log("OnDownload " + e);
+
+ this.fileExplorerServices.OpenDownload(e);
+ });
+ }
+
+ OnDeleteClick(sender) {
+
+ let selected = this.props.ParentComponent.refs.
+ FileExplorerControl.GetSelectedID();
+ let promises = [];
+
+ selected.map((e) => {
+ console.log("OnDelete " + e);
+
+ promises.push(
+ this.fileExplorerServices.DeleteAsync(e)
+ );
+ });
+
+ Promise.all(promises).
+ then(function (res) {
+
+ let promises = [];
+ res.map((e) => {
+ promises.push(e.json());
+ })
+
+ let Result = "";
+
+ Promise.all(promises).
+ then(function (data) {
+
+ data.map(function (e) {
+ Result += "Succese: " + e.Successe + " ResultMsg:" + e.ResMessage + " | ";
+ });
+
+ this.setState({ ResultMsg: Result });
+ this.props.
+ ParentComponent.OnItemsChange();
+ }.bind(this));
+
+ }.bind(this)
+ )
+ }
+
+
+ OnMoveClick(sender) {
+ //GetSelectedFiles
+
+ //New sub windows for select path to move
+ }
+
+ OnCreateDirectoryClick(sender) {
+ let dirname = this.refs.DirectoryName.value;
+ let id = this.props.ParentComponent.GetID();
+
+ let url = "/Explorer/CreateDirectory?ParentID=" + id
+ + "&Name=" + dirname;
+
+ this.fileExplorerServices.CreateDirectoryAsync(dirname, id).
+ then(function (response) {
+ response.json().then(function (data) {
+ this.props.ParentComponent.OnItemsChange();
+ }.bind(this));
+ }.bind(this));
+
+ this.refs.DirectoryName.value = "";
+ }
+
+ render() {
+
+ return (
+ <div>
+ <p>ExplorerControlPanel</p>
+
+ <p>
+ <input ref="DirectoryName" />
+ <button onClick={this.OnCreateDirectoryClick}>CreateDirectory</button>
+ </p>
+
+ {
+ (
+ () => {
+ if (this.state.ResultMsg != "") {
+ return <p>{this.state.ResultMsg}</p>
+ }
+ }).bind(this)()
+ }
+
+ <table>
+ <tr>
+ <th><button onClick={this.OnDownloadClick}>Скачать</button></th>
+ <th><button onClick={this.OnDeleteClick}>Удалить</button></th>
+ <th><button>Переместить</button></th>
+ </tr>
+ </table>
+ </div>
+ );
+
+ }
+}
FileServer/Web/Scripts/React/FileExplorerControl.jsx 165(+165 -0)
diff --git a/FileServer/Web/Scripts/React/FileExplorerControl.jsx b/FileServer/Web/Scripts/React/FileExplorerControl.jsx
new file mode 100644
index 0000000..b5082aa
--- /dev/null
+++ b/FileServer/Web/Scripts/React/FileExplorerControl.jsx
@@ -0,0 +1,165 @@
+
+class FileExplorerControl extends React.Component {
+
+ constructor(props) {
+ super(props);
+ console.log('FileExplorer start');
+
+ this.state = { data: {} };
+ this.ChildRows = [];
+ this.fileExplorerServices = new FileExplorerServices();
+
+ //#region Binding
+
+ this.GetID = this.props.GetID;
+ this.SetID = this.props.SetID;
+
+ this.LoadData = this.LoadDirectory.bind(this);
+ this.OnBackClick = this.OnBackClick.bind(this);
+ this.OnDirectoryClick = this.OnDirectoryClick.bind(this);
+ this.OnScanDirClick = this.OnScanDirClick.bind(this);
+ this.OnSortClick = this.OnSortClick.bind(this);
+
+ //#endregion
+
+ this.LoadDirectory();
+ }
+
+ //#endregion
+
+ //#region Events
+
+ OnBackClick(sender) {
+ this.SetID(this.state.data.ParentID);
+
+ console.log("OnBackClick " + this.state.data.ParentID);
+
+ //this.state = { ID: new_id };
+ this.LoadDirectory();
+ }
+
+ OnDirectoryClick(id) {
+ this.SetID(id);
+
+ console.log("MoveToDirectory " + id);
+
+ //this.state = { ID: new_id };
+ this.LoadDirectory();
+ }
+
+ OnSortClick(sender) {
+ let SortProperty = sender.target.attributes[0].value;
+
+ let data = this.state.data;
+ //debugger;
+ data.items.sort(ArrayCompare(SortProperty, 1));
+ this.setState({ data: data });
+ }
+
+
+ //#endregion
+
+ //Загружает информацию о текущей папке
+ LoadDirectory() {
+ let ID = this.GetID();
+ console.log("LoadDirectory " + ID);
+
+ this.fileExplorerServices.DirectoryGetItemsAsync(ID)
+ .then(function (response) {
+ response.json().then(function (data) {
+ this.setState({ data: data });
+ }.bind(this));
+ }.bind(this));
+ }
+
+ OnScanDirClick(sender) {
+ let ID = this.GetID();
+ console.log("ScanDirectory " + ID);
+
+ this.fileExplorerServices.ScanDirectoryAsync(ID).then(function (response) {
+ response.json().then(function (data) {
+ this.LoadData();;
+ }.bind(this));
+ }.bind(this));
+ }
+
+ //Получить ID данных выбранных строк
+ GetSelectedID() {
+ //debugger;
+ return this.ChildRows.
+ filter(e => e.IsCheked()).
+ map(e => e.GetDataID());
+ }
+
+ render() {
+ this.ChildRows = [];
+ let data = this.state.data;
+
+ //Если данные не пусты
+ if (JSON.stringify(data) !== '{}') {
+ console.log("Data");
+
+ return (
+ <div>
+ <p>
+ <Link to={`/?ID=${data.ParentID}`}>
+ <button onClick={this.OnBackClick}>
+ l- На уровень вверх - {data.ParentName}
+ </button>
+ </Link>
+ </p>
+ <p>{data.LogicPath}</p>
+ <p>
+ <button onClick={this.LoadData}>
+ Update
+ </button>
+ <button onClick={this.OnScanDirClick}>
+ Rescan
+ </button>
+ </p>
+
+
+ <table class="table">
+ <tr>
+ <th>
+ <button property="ID" onClick={this.OnSortClick}>ID</button>
+ </th>
+ <th>Select</th>
+ <th>
+ <button property="Name" onClick={this.OnSortClick}>Name</button>
+ </th>
+ <th>
+ <button property="Type" onClick={this.OnSortClick}>Type</button>
+ </th>
+ <th>
+ <button property="Size" onClick={this.OnSortClick}>Size</button>
+ </th>
+ <th></th>
+ </tr>
+
+ {
+ data.items.map(function (elem, i, arr) {
+ return [
+ <FileExplorerRow ref={row => this.ChildRows[i] = row}
+ ID={i}
+ data={elem}
+ ParentComponent={this}
+ />
+ ];
+ }.bind(this))
+ }
+ </table>
+ </div>
+ );
+ }
+ else {
+ console.log("NoData");
+
+ return (
+ <div>
+ <p>NoData</p>
+ </div>
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/FileServer/Web/Scripts/React/FileExplorerRow.jsx b/FileServer/Web/Scripts/React/FileExplorerRow.jsx
new file mode 100644
index 0000000..6733978
--- /dev/null
+++ b/FileServer/Web/Scripts/React/FileExplorerRow.jsx
@@ -0,0 +1,89 @@
+
+class FileExplorerRow extends React.Component {
+
+ constructor(props) {
+ super(props);
+ console.log('FileExplorerRow start ' + this.props.ID);
+
+ this.state = { ID: this.props.ID, Data: this.props.data };
+
+ this.GetDate = this.GetDate.bind(this);
+ this.GetRowID = this.GetRowID.bind(this);
+ this.GetDataID = this.GetDataID.bind(this);
+ this.IsCheked = this.IsCheked.bind(this);
+ this.OnDirectoryClick = this.OnDirectoryClick.bind(this);
+ }
+
+ componentWillReceiveProps(nextProps) {
+ this.props = nextProps;
+ this.setState({ ID: this.props.ID, Data: this.props.data });
+ }
+
+ GetDate() {
+ return this.state.Data;
+ }
+
+ GetRowID() {
+ return this.state.ID;
+ }
+ GetDataID() {
+ return this.state.Data.ID;
+ }
+ IsCheked() {
+ if (this.refs.Select == undefined)
+ return false;
+
+ return this.refs.Select.checked;
+ }
+
+
+ OnDirectoryClick() {
+ this.props.ParentComponent.OnDirectoryClick(this.GetDataID());
+ }
+
+ render() {
+ let state = this.state;
+ let elem = state.Data;
+
+ return (
+ <tr>
+ <td>{elem.ID}</td>
+ {
+ (() => {
+ if (elem.Type === "RootDirectory" || elem.Type === "Directory") {
+ return (
+ <td></td>
+ )
+ }
+ else {
+ return (
+ <td><input ref="Select" type="checkbox" /></td>
+ )
+ }
+ }).bind(this)()
+ }
+
+ <td>{elem.Name}</td>
+ <td>{elem.Type}</td>
+ <td>{elem.Size}</td>
+
+ {
+ (() => {
+ if (elem.Type === "RootDirectory" || elem.Type === "Directory") {
+ return (
+ <td><Link to={`/?ID=${elem.ID}`}><button id={elem.ID} onClick={this.OnDirectoryClick}>
+ Перейти</button></Link></td>
+ )
+ }
+ else {
+ return (
+ <td></td>
+ )
+ }
+ }).bind(this)()
+ }
+ </tr>
+ );
+
+ }
+}
\ No newline at end of file
FileServer/Web/Scripts/React/RouteSystem.jsx 27(+27 -0)
diff --git a/FileServer/Web/Scripts/React/RouteSystem.jsx b/FileServer/Web/Scripts/React/RouteSystem.jsx
new file mode 100644
index 0000000..2835f46
--- /dev/null
+++ b/FileServer/Web/Scripts/React/RouteSystem.jsx
@@ -0,0 +1,27 @@
+
+
+
+class RouteSystem extends React.Component {
+
+ constructor(props) {
+ super(props);
+ console.log('RouteSystem start');
+ }
+
+ render() {
+ return (
+ <Router>
+ <Switch>
+ <Route path="/" component={() => <App ID="-1" />} />
+ <Route path="/?ID=:ID" component={App} />
+ </Switch>
+ </Router>
+ );
+ }
+}
+
+ReactDOM.render(
+ <RouteSystem />,
+ document.getElementById("app")
+)
+
FileServer/Web/Scripts/React/UploaderControl.jsx 101(+101 -0)
diff --git a/FileServer/Web/Scripts/React/UploaderControl.jsx b/FileServer/Web/Scripts/React/UploaderControl.jsx
new file mode 100644
index 0000000..6fa200c
--- /dev/null
+++ b/FileServer/Web/Scripts/React/UploaderControl.jsx
@@ -0,0 +1,101 @@
+
+class UploaderControl extends React.Component {
+
+ constructor(props) {
+ super(props);
+ console.log('Uploader start');
+
+ //state 0 - выбор файла
+ //state 1 - загрузка
+ this.state = { progress: 0, ButtonUploadEnable: true, _state: 0, FileInfo: {}, ResultMsg: "" };
+
+ this.GetID = this.props.GetID;
+
+ this.UploadClick = this.UploadClick.bind(this);
+ this.CancelClick = this.CancelClick.bind(this);
+
+ this.OnProgresseChange = this.OnProgresseChange.bind(this);
+ this.OnError = this.OnError.bind(this);
+
+ this.uploadServices = new UploadServices();
+ this.uploadServices.OnProggresseChange = this.OnProgresseChange;
+ //this.uploadServices.OnIDReceived = null;
+ this.uploadServices.OnError = this.OnError;
+ }
+
+ UploadClick() {
+
+ let input = this.refs.file;
+ let files = input.files;
+
+
+ if (files.length == 0)
+ return;
+ let file = files[0];
+
+ this.setState({ ButtonUploadEnable: false, _state: 1, FileInfo: { name: file.name, size: file.size } });
+
+ this.uploadServices.UploadFileAsync(file, this.GetID()).then(function () {
+ this.setState({ ButtonUploadEnable: true, _state: 0, FileInfo: {} });
+ this.props.OnItemsChange();
+ input.value = "";
+ }.bind(this));
+ }
+
+ CancelClick() {
+ this.uploadServices.Cansel();
+ this.setState({ ButtonUploadEnable: true, _state: 0, FileInfo: {} });
+ }
+
+ OnProgresseChange(Process) {
+ this.setState({ progress: Process });
+ }
+
+ OnError(Msg) {
+ this.setState({ progress: 0, ButtonUploadEnable: true, _state: 0, FileInfo: {}, ResultMsg: Msg });
+ }
+
+
+
+ render() {
+ return (
+ <div>
+ <h2>Upload</h2>
+ <p>
+ <input ref="file" type="file" disabled={!this.state.ButtonUploadEnable} />
+ <input type="button" disabled={!this.state.ButtonUploadEnable} onClick={this.UploadClick} value='Upload' />
+ <input type="button" disabled={this.state.ButtonUploadEnable} onClick={this.CancelClick} value='Cancel' />
+ </p>
+
+ {
+ (
+ () => {
+ if (this.state._state == 1) {
+ return (
+ <div>
+ <p>Прогресс {this.state.progress} %</p>
+ <p>Выполняется загрука файла:</p>
+ <p>Имя файла: {this.state.FileInfo.name}</p>
+ <p>Размеры файла: {this.state.FileInfo.size}</p>
+ </div>
+ )
+ }
+ }
+ ).bind(this)()
+ }
+
+ {
+ (
+ () => {
+ if (this.state.ResultMsg != "") {
+ return (
+ <p>Результат: {this.state.ResultMsg}</p>
+ )
+ }
+ }
+ ).bind(this)()
+ }
+ </div>
+ );
+ }
+}
\ No newline at end of file
FileServer/Web/Scripts/React/UserControl.jsx 78(+78 -0)
diff --git a/FileServer/Web/Scripts/React/UserControl.jsx b/FileServer/Web/Scripts/React/UserControl.jsx
new file mode 100644
index 0000000..8e01bb0
--- /dev/null
+++ b/FileServer/Web/Scripts/React/UserControl.jsx
@@ -0,0 +1,78 @@
+
+class UserControl extends React.Component {
+
+ constructor(props) {
+ super(props);
+ console.log('UserControl start');
+
+ this.state = { UserName: "", AuthResult: "" };
+ this.userServices = new UserServices();
+
+ this.AuthClick = this.AuthClick.bind(this);
+ this.LogoutClick = this.LogoutClick.bind(this);
+ }
+
+ //Кнопка входа
+ AuthClick() {
+ let login = this.refs.Login.value;
+ let password = this.refs.Password.value;
+
+ this.userServices.Auth(login, password)
+ .then(function (response) {
+ response.json().then(function (data) {
+
+ if (data.Successe) {
+ this.userServices.SetTocken(data.Token);
+ this.setState({ UserName: data.UserName, AuthResult: "" });
+ }
+ else {
+ this.userServices.SetTocken("");
+ this.setState({ UserName: "", AuthResult: data.ResMsg });
+ }
+
+ }.bind(this));
+ }.bind(this));
+ }
+
+ //Кнопка выхода
+ LogoutClick() {
+ this.userServices.SetTocken("");
+ this.setState({ UserName: "", AuthResult: "" });
+ }
+
+
+ render() {
+ let state = this.state;
+
+
+ if (this.userServices.IsAuth()) {
+ return (
+ <div>
+ <p>Вы авторизованы. Пользователь: {state.UserName}.</p>
+ <button onClick={this.LogoutClick}>Logout</button>
+ </div>
+ );
+ }
+ else {
+ return (
+ <div>
+ <p>Вы не авторизованы {state.UserName}. Вход:</p>
+
+ {(() => {
+
+ if (state.AuthResult != "") {
+ return <p>{state.AuthResult}</p>;
+ }
+ }).bind(this)()
+ }
+
+ <input ref="Login" />
+ <br />
+ <input ref="Password" />
+ <br />
+ <button onClick={this.AuthClick}>Auth</button>
+ </div>
+ );
+ }
+ }
+}
\ No newline at end of file
diff --git a/FileServer/Web/Scripts/Services/FileExplorerServices.js b/FileServer/Web/Scripts/Services/FileExplorerServices.js
new file mode 100644
index 0000000..fdcefc3
--- /dev/null
+++ b/FileServer/Web/Scripts/Services/FileExplorerServices.js
@@ -0,0 +1,57 @@
+
+class FileExplorerServices {
+ constructor() {
+
+ this.URL_DirectoryItems = "/Explorer/GetDirectoryItems?ID=";
+ this.URL_ScanDirectory = "/Explorer/ScanDirectory?ID=";
+
+ this.URL_Delete = "/Explorer/DeleteFile?ID=";
+ this.URL_Download = "/Explorer/GetFile?ID=";
+ this.URL_CreateDirectory = "/Explorer/CreateDirectory?";
+
+
+ }
+
+
+ async DirectoryGetItemsAsync(ID) {
+ let url = this.URL_DirectoryItems + ID;
+
+ return fetch(
+ url,
+ {
+ ID: ID
+ })
+ }
+
+ async ScanDirectoryAsync(ID) {
+ let url = this.URL_ScanDirectory + ID;
+
+ return fetch(url);
+ }
+
+
+ async DeleteAsync(ID) {
+ let url = this.URL_Delete + ID;
+
+ return fetch(
+ url,
+ {
+ method: 'POST'
+ }
+ )
+ }
+
+ OpenDownload(ID) {
+ let url = this.URL_Download + ID;
+
+ window.open(url, '_blank');
+ }
+
+ async CreateDirectoryAsync(dirname, id) {
+ let url = this.URL_CreateDirectory+"ParentID = " + id
+ + "&Name=" + dirname;
+
+ return fetch(url);
+ }
+
+}
\ No newline at end of file
FileServer/Web/Scripts/Services/UploadServices.js 149(+149 -0)
diff --git a/FileServer/Web/Scripts/Services/UploadServices.js b/FileServer/Web/Scripts/Services/UploadServices.js
new file mode 100644
index 0000000..a930cb2
--- /dev/null
+++ b/FileServer/Web/Scripts/Services/UploadServices.js
@@ -0,0 +1,149 @@
+
+class UploadServices {
+
+ constructor() {
+
+ this.URL_Start = "/UploadFiles/StartUpload";
+ this.URL_Upload = "/UploadFiles/UploadBlob";
+ this.URL_Cansel = "/UploadFiles/Cansel";
+
+ this.upload_chunk_size = 102400;
+ this.ID = -1;
+
+ this._ContinueDownload = false;
+
+ this._file = null;
+ this._ParentID = null;
+
+ //Callback события
+ //(number progresse)
+ this.OnProggresseChange = null;
+ //(number id)
+ this.OnIDReceived = null;
+ //(string Msg)
+ this.OnError = null;
+ }
+
+
+ //Считывает часть файла
+ //startByte - int позиция начала чтения
+ //stopByte - int позиция окончания чтения
+ async _ReadBlobAsync(startByte, stopByte) {
+
+ return new Promise(function (resolve, reject) {
+ //Считываем часть файла
+ let blob = this._file.slice(startByte, stopByte);
+
+ let reader = new FileReader();
+ reader.onload = function () {
+ resolve(reader.result);
+ };
+ reader.onerror = reject;
+
+ reader.readAsDataURL(blob);
+ }.bind(this));
+ }
+
+ //Сообщает серверу о начале загрузки файла, получает ID загрузки
+ async _StartUploadAsync() {
+ return await $.post(this.URL_Start,
+ {
+ //ID папки
+ 'ParentID': this._ParentID,
+ //Имя файла
+ 'Name': this._file.name,
+ //Размеры
+ 'Size': this._file.size
+ }
+ );
+ }
+
+ //Выполняет загрузка блока
+ async _UploadBlobAsync(bin_data, ChunkNumb) {
+
+ if (!this._ContinueDownload)
+ return { State: true };
+
+
+ if (bin_data != '') {
+ console.log(this.URL_Upload + ChunkNumb);
+
+ var state = await $.post(this.URL_Upload,
+ {
+ //ID загрузки
+ 'ID': this.ID,
+ //Кусок файла
+ 'chunk': bin_data,
+ //Номер куска
+ //'ChunkNumb': ChunkNumb
+ }
+ )
+
+ return state;
+ }
+ }
+
+
+ //Инициирует загрузку файла
+ //parent_id - int ID папки для загрузки
+ async UploadFileAsync(file, parent_id) {
+
+ this._file = file;
+ this._ParentID = parent_id;
+
+ let start_info = await this._StartUploadAsync();
+ if (!start_info.State) {
+ if (this.OnError != null)
+ this.OnError(start_info.Msg);
+ return;
+ }
+
+ this._ContinueDownload = true;
+ this.ID = start_info.ID;
+ if (this.OnIDReceived != null)
+ this.OnIDReceived(this.ID);
+
+ for (let pos = 0, ChunkNumb = 0; pos < this._file.size; pos += this.upload_chunk_size, ChunkNumb++) {
+ if (!this._ContinueDownload)
+ return;
+
+ let bin_data = await this._ReadBlobAsync(pos, pos + this.upload_chunk_size);
+ let state = await this._UploadBlobAsync(bin_data, ChunkNumb);
+
+ if (!state.State) {
+ //alert('Загрузка прервана');
+
+ if (this.OnError != null)
+ this.OnError(state.Msg);
+ return;
+ }
+
+ // Вычисляем процент отправленного
+ let p = Math.round(pos * 100 / file.size);
+ console.log('p = ' + p);
+
+ if (this.OnProggresseChange != null)
+ this.OnProggresseChange(p);
+ }
+
+ this._ContinueDownload = false;
+ }
+
+ Cansel() {
+ this._ContinueDownload = false;
+
+ //Костыль задержка, чтобы асинхронный загрузчик точно прервал работу
+ //и не попытался получить доступ к ужаленному проекту загрузки
+ //Возможно зависит от размера блока
+ setTimeout(function () {
+ $.post(this.URL_Cansel,
+ {
+ //Имя файла
+ 'ID': this.ID,
+ }
+ )
+ }.bind(this),
+ 500);
+ }
+
+}
diff --git a/FileServer/Web/Scripts/Services/UserServices.js b/FileServer/Web/Scripts/Services/UserServices.js
new file mode 100644
index 0000000..cf8f52c
--- /dev/null
+++ b/FileServer/Web/Scripts/Services/UserServices.js
@@ -0,0 +1,52 @@
+
+class UserServices {
+
+ constructor() {
+
+ this.URL_Auth = "/User/Auth?";
+
+ }
+
+
+
+ Auth(login, password) {
+
+ let url = this.URL_Auth + "Login=" + login + "&Password=" + password;
+
+ return fetch(
+ url,
+ {
+ //Login: login,
+ //Password: password
+ });
+ }
+
+ //Возвращает true если пользователь авторизован
+ IsAuth() {
+ let token = this.GetTocken();
+ return token != "";
+ }
+
+ _getCookie(name) {
+ let matches = document.cookie.match(new RegExp(
+ "(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
+ ));
+ return matches ? decodeURIComponent(matches[1]) : "";
+ }
+
+ //Токен авторизации
+ GetTocken() {
+ return this._getCookie("AuthToken");
+ }
+ //задать токен
+ SetTocken(val) {
+ document.cookie = "AuthToken=" + val;
+ }
+
+ //Возвращает true если пользователь авторизован
+ IsAuth() {
+ let token = this.GetTocken();
+ return token != "";
+ }
+
+}
FileServer/Web/Scripts/Tools/Sort.js 64(+64 -0)
diff --git a/FileServer/Web/Scripts/Tools/Sort.js b/FileServer/Web/Scripts/Tools/Sort.js
new file mode 100644
index 0000000..fab72ea
--- /dev/null
+++ b/FileServer/Web/Scripts/Tools/Sort.js
@@ -0,0 +1,64 @@
+//https://habr.com/ru/post/279867/
+
+
+////Использование
+//arr.sort(ArrayCompare()); //Обычная типобезопасная сортировка по возрастанию
+//arr.sort(ArrayCompare(-1)); //Обычная типобезопасная сортировка по убыванию
+//arr.sort(ArrayCompare('field')); //Сортировка по свойству field по возрастанию
+//arr.sort(ArrayCompare('field', -1)); //Сортировка по свойству field по убыванию
+///* Сортировка сначала по полю field1
+// при совпадении по полю field2, а если и оно совпало, то по полю field3
+// все по возрастанию */
+//arr.sort(compare('field1', 'field2', 'field3'));
+///* Сортировка сначала по полю field1 по возрастанию
+// при совпадении по полю field2 по убыванию */
+//arr.sort(compare({
+// field1: 1,
+// field2: -1
+//}));
+
+
+//Метод сравнения элементов для сортировки
+//field - имя свойства сущности
+//order порядок 0 - возрастание, 1 - убывание
+function ArrayCompare(field, order) {
+ var len = arguments.length;
+ if (len === 0) {
+ return (a, b) => (a < b && -1) || (a > b && 1) || 0;
+ }
+ if (len === 1) {
+ switch (typeof field) {
+ case 'number':
+ return field < 0 ?
+ ((a, b) => (a < b && 1) || (a > b && -1) || 0) :
+ ((a, b) => (a < b && -1) || (a > b && 1) || 0);
+ case 'string':
+ return (a, b) => (a[field] < b[field] && -1) || (a[field] > b[field] && 1) || 0;
+ }
+ }
+ if (len === 2 && typeof order === 'number') {
+ return order < 0 ?
+ ((a, b) => (a[field] < b[field] && 1) || (a[field] > b[field] && -1) || 0) :
+ ((a, b) => (a[field] < b[field] && -1) || (a[field] > b[field] && 1) || 0);
+ }
+ var fields, orders;
+ if (typeof field === 'object') {
+ fields = Object.getOwnPropertyNames(field);
+ orders = fields.map(key => field[key]);
+ len = fields.length;
+ } else {
+ fields = new Array(len);
+ orders = new Array(len);
+ for (let i = len; i--;) {
+ fields[i] = arguments[i];
+ orders[i] = 1;
+ }
+ }
+ return (a, b) => {
+ for (let i = 0; i < len; i++) {
+ if (a[fields[i]] < b[fields[i]]) return orders[i];
+ if (a[fields[i]] > b[fields[i]]) return -orders[i];
+ }
+ return 0;
+ };
+}
\ No newline at end of file
diff --git a/FileServer/Web/Views/_ViewStart.cshtml b/FileServer/Web/Views/_ViewStart.cshtml
new file mode 100644
index 0000000..2de6241
--- /dev/null
+++ b/FileServer/Web/Views/_ViewStart.cshtml
@@ -0,0 +1,3 @@
+@{
+ Layout = "~/Views/Shared/_Layout.cshtml";
+}
diff --git a/FileServer/Web/Views/Home/About.cshtml b/FileServer/Web/Views/Home/About.cshtml
new file mode 100644
index 0000000..4b2d9e8
--- /dev/null
+++ b/FileServer/Web/Views/Home/About.cshtml
@@ -0,0 +1,7 @@
+@{
+ ViewBag.Title = "About";
+}
+<h2>@ViewBag.Title.</h2>
+<h3>@ViewBag.Message</h3>
+
+<p>Use this area to provide additional information.</p>
FileServer/Web/Views/Home/Contact.cshtml 17(+17 -0)
diff --git a/FileServer/Web/Views/Home/Contact.cshtml b/FileServer/Web/Views/Home/Contact.cshtml
new file mode 100644
index 0000000..0f4327e
--- /dev/null
+++ b/FileServer/Web/Views/Home/Contact.cshtml
@@ -0,0 +1,17 @@
+@{
+ ViewBag.Title = "Contact";
+}
+<h2>@ViewBag.Title.</h2>
+<h3>@ViewBag.Message</h3>
+
+<address>
+ One Microsoft Way<br />
+ Redmond, WA 98052-6399<br />
+ <abbr title="Phone">P:</abbr>
+ 425.555.0100
+</address>
+
+<address>
+ <strong>Support:</strong> <a href="mailto:Support@example.com">Support@example.com</a><br />
+ <strong>Marketing:</strong> <a href="mailto:Marketing@example.com">Marketing@example.com</a>
+</address>
\ No newline at end of file
FileServer/Web/Views/Home/Index.cshtml 69(+69 -0)
diff --git a/FileServer/Web/Views/Home/Index.cshtml b/FileServer/Web/Views/Home/Index.cshtml
new file mode 100644
index 0000000..8bf9f77
--- /dev/null
+++ b/FileServer/Web/Views/Home/Index.cshtml
@@ -0,0 +1,69 @@
+
+@{
+ /**/
+
+ ViewBag.Title = "Index";
+}
+
+<h2>Index</h2>
+
+<div id="app"> </div>
+
+@section Scripts {
+ @* React *@
+ <script crossorigin src="https://unpkg.com/react@16/umd/react.production.min.js"></script>
+ <script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.production.min.js"></script>
+ <script src="https://unpkg.com/react-router-dom/umd/react-router-dom.min.js"></script>
+ @* Babel *@
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.25.0/babel.min.js"></script>
+
+ @* React-Bootstrap *@
+ <script crossorigin type="text/babel" src="https://unpkg.com/react-bootstrap@next/dist/react-bootstrap.min.js"></script>
+
+ @* Bootstrap stile
+ <link rel="stylesheet"
+ href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
+ integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T"
+ crossorigin="anonymous" />
+ *@
+
+
+ <script type="text/babel">
+ @* ReactComponents *@
+
+ const Router = ReactRouterDOM.BrowserRouter;
+ const Route = ReactRouterDOM.Route;
+ const Switch = ReactRouterDOM.Switch;
+ const Link = ReactRouterDOM.Link;
+
+ @* BootstrapComponents *@
+ const ButtonToolbar = ReactBootstrap.ButtonToolbar;
+ const Button = ReactBootstrap.Button;
+ </script>
+
+
+ @* Application scripts *@
+ @Scripts.RenderFormat("<script type ='text/babel' src='{0}' defer></script>",
+
+ "/Scripts/React/BootstrapControl.jsx?" + DateTime.Now,
+
+
+ "/Scripts/Services/UserServices.js?" + DateTime.Now,
+ "/Scripts/React/UserControl.jsx?" + DateTime.Now,
+
+
+ "/Scripts/Services/UploadServices.js?" + DateTime.Now,
+ "/Scripts/React/UploaderControl.jsx?" + DateTime.Now,
+
+
+ "/Scripts/Tools/Sort.js?" + DateTime.Now,
+ "/Scripts/Services/FileExplorerServices.js?" + DateTime.Now,
+ "/Scripts/React/FileExplorerRow.jsx?" + DateTime.Now,
+ "/Scripts/React/FileExplorerControl.jsx?" + DateTime.Now,
+ "/Scripts/React/ExplorerActionsControl.jsx?" + DateTime.Now,
+
+
+ "/Scripts/React/App.jsx?" + DateTime.Now,
+ "/Scripts/React/RouteSystem.jsx?" + DateTime.Now
+ )
+}
FileServer/Web/Views/Shared/_Layout.cshtml 44(+44 -0)
diff --git a/FileServer/Web/Views/Shared/_Layout.cshtml b/FileServer/Web/Views/Shared/_Layout.cshtml
new file mode 100644
index 0000000..ffd231a
--- /dev/null
+++ b/FileServer/Web/Views/Shared/_Layout.cshtml
@@ -0,0 +1,44 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <meta charset="utf-8" />
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>@ViewBag.Title – приложение ASP.NET</title>
+ @Styles.Render("~/Content/css")
+ @Scripts.Render("~/bundles/modernizr")
+</head>
+<body>
+ <nav class="navbar navbar-expand-sm navbar-dark fixed-top bg-dark">
+ <div class="container">
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"></button>
+ <a class="navbar-brand" href="/">WebFileServer</a>
+ <div class="navbar-collapse collapse" id="navbarSupportedContent">
+ <ul class="nav navbar-nav mr-auto">
+ <li class="nav-item"><a href="/" class="nav-link">App</a></li>
+ @*<li class="nav-item"><a href="/Home/About" class="nav-link">About</a></li>
+ <li class="nav-item"><a href="/Home/Contact" class="nav-link">Contact</a></li>*@
+ </ul>
+
+ @*<ul class="nav navbar-nav navbar-right mr-auto">
+ <li class="nav-item"><a href="/Account/Register" id="registerLink" class="nav-link">Register</a></li>
+ <li class="nav-item"><a href="/Account/Login" id="loginLink" class="nav-link">Log in</a></li>
+ </ul>*@
+
+ </div>
+ </div>
+ </nav>
+
+ <div class="container body-content">
+ @RenderBody()
+ <hr />
+ <footer>
+ <p>© @DateTime.Now.Year – приложение ASP.NET</p>
+ </footer>
+ </div>
+
+ @Scripts.Render("~/bundles/jquery")
+ @Scripts.Render("~/bundles/bootstrap")
+ @RenderSection("scripts", required: false)
+</body>
+</html>
FileServer/Web/Views/Shared/Error.cshtml 14(+14 -0)
diff --git a/FileServer/Web/Views/Shared/Error.cshtml b/FileServer/Web/Views/Shared/Error.cshtml
new file mode 100644
index 0000000..ca2bcaf
--- /dev/null
+++ b/FileServer/Web/Views/Shared/Error.cshtml
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
+ <meta name="viewport" content="width=device-width" />
+ <title>Ошибка</title>
+</head>
+<body>
+ <hgroup>
+ <h1>Ошибка.</h1>
+ <h2>При обработке запроса произошла ошибка.</h2>
+ </hgroup>
+</body>
+</html>
FileServer/Web/Views/Web.config 43(+43 -0)
diff --git a/FileServer/Web/Views/Web.config b/FileServer/Web/Views/Web.config
new file mode 100644
index 0000000..e8fdead
--- /dev/null
+++ b/FileServer/Web/Views/Web.config
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+
+<configuration>
+ <configSections>
+ <sectionGroup name="system.web.webPages.razor" type="System.Web.WebPages.Razor.Configuration.RazorWebSectionGroup, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35">
+ <section name="host" type="System.Web.WebPages.Razor.Configuration.HostSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
+ <section name="pages" type="System.Web.WebPages.Razor.Configuration.RazorPagesSection, System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" requirePermission="false" />
+ </sectionGroup>
+ </configSections>
+
+ <system.web.webPages.razor>
+ <host factoryType="System.Web.Mvc.MvcWebRazorHostFactory, System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ <pages pageBaseType="System.Web.Mvc.WebViewPage">
+ <namespaces>
+ <add namespace="System.Web.Mvc" />
+ <add namespace="System.Web.Mvc.Ajax" />
+ <add namespace="System.Web.Mvc.Html" />
+ <add namespace="System.Web.Optimization"/>
+ <add namespace="System.Web.Routing" />
+ <add namespace="Web" />
+ </namespaces>
+ </pages>
+ </system.web.webPages.razor>
+
+ <appSettings>
+ <add key="webpages:Enabled" value="false" />
+ </appSettings>
+
+ <system.webServer>
+ <handlers>
+ <remove name="BlockViewHandler"/>
+ <add name="BlockViewHandler" path="*" verb="*" preCondition="integratedMode" type="System.Web.HttpNotFoundHandler" />
+ </handlers>
+ </system.webServer>
+
+ <system.web>
+ <compilation>
+ <assemblies>
+ <add assembly="System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
+ </assemblies>
+ </compilation>
+ </system.web>
+</configuration>
FileServer/Web/Web.config 117(+117 -0)
diff --git a/FileServer/Web/Web.config b/FileServer/Web/Web.config
new file mode 100644
index 0000000..e7310eb
--- /dev/null
+++ b/FileServer/Web/Web.config
@@ -0,0 +1,117 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Дополнительные сведения о настройке приложения ASP.NET см. на странице
+ https://go.microsoft.com/fwlink/?LinkId=301880
+ -->
+<configuration>
+ <configSections>
+ <!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
+ <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
+ </configSections>
+ <!--<system.web.extensions>
+ <scripting>
+ <webServices>
+ <jsonSerialization recursionLimit="2"/>
+ </webServices>
+ </scripting>
+ </system.web.extensions>-->
+ <appSettings>
+ <add key="webpages:Version" value="3.0.0.0" />
+ <add key="webpages:Enabled" value="false" />
+ <add key="ClientValidationEnabled" value="true" />
+ <add key="UnobtrusiveJavaScriptEnabled" value="true" />
+ <add key="WorkFolder" value="C:\Users\cccc1808\source\repos\FileServer\Console\bin\Debug\Dir1;C:\Users\cccc1808\source\repos\FileServer\Console\bin\Debug\Dir2" />
+ </appSettings>
+ <!--
+ Описание изменений web.config см. по адресу http://go.microsoft.com/fwlink/?LinkId=235367.
+
+ Следующие атрибуты можно установить с помощью тега <httpRuntime>.
+ <system.Web>
+ <httpRuntime targetFramework="4.5.2" />
+ </system.Web>
+ -->
+ <system.web>
+ <compilation debug="true" targetFramework="4.5.2" />
+ <httpRuntime targetFramework="4.5" />
+ <httpModules>
+ <add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" />
+ </httpModules>
+ </system.web>
+ <runtime>
+ <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+ <dependentAssembly>
+ <assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" />
+ <bindingRedirect oldVersion="0.0.0.0-3.5.0.2" newVersion="3.5.0.2" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" />
+ <bindingRedirect oldVersion="0.0.0.0-4.0.3.1" newVersion="4.0.3.1" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
+ <bindingRedirect oldVersion="0.0.0.0-12.0.0.0" newVersion="12.0.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Optimization" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-1.1.0.0" newVersion="1.1.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Helpers" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
+ </dependentAssembly>
+ <dependentAssembly>
+ <assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
+ <bindingRedirect oldVersion="1.0.0.0-5.2.7.0" newVersion="5.2.7.0" />
+ </dependentAssembly>
+ </assemblyBinding>
+ </runtime>
+ <system.webServer>
+ <modules>
+ <remove name="TelemetryCorrelationHttpModule" />
+ <add name="TelemetryCorrelationHttpModule" type="Microsoft.AspNet.TelemetryCorrelation.TelemetryCorrelationHttpModule, Microsoft.AspNet.TelemetryCorrelation" preCondition="managedHandler" />
+ </modules>
+
+ <handlers>
+ <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
+ <remove name="OPTIONSVerbHandler" />
+ <remove name="TRACEVerbHandler" />
+ <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
+ </handlers>
+ <validation validateIntegratedModeConfiguration="false" />
+ </system.webServer>
+ <entityFramework>
+ <defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework">
+ <parameters>
+ <parameter value="mssqllocaldb" />
+ </parameters>
+ </defaultConnectionFactory>
+ <providers>
+ <provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" />
+ </providers>
+ </entityFramework>
+
+ <connectionStrings>
+
+ <!--Sqllocaldb-->
+ <add name="DBConnection" connectionString="data source=(localdb)\MSSQLLocalDB;Initial Catalog=FS;Integrated Security=True; MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
+
+ <!--MS SQL Express-->
+ <!-- .\ - WIN-2016-SERVER -->
+ <!--<add name="DBConnection" connectionString="data source=.\SQLEXPRESS;Initial Catalog=MSSQLLocalDB;User ID=SQL_User;Password=link; MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />-->
+
+ </connectionStrings>
+ <system.codedom>
+ <compilers>
+ <compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:6 /nowarn:1659;1699;1701" />
+ <compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:14 /nowarn:41008 /define:_MYTYPE=\"Web\" /optionInfer+" />
+ </compilers>
+ </system.codedom>
+</configuration>
\ No newline at end of file
FileServer/Web/Web.csproj 311(+311 -0)
diff --git a/FileServer/Web/Web.csproj b/FileServer/Web/Web.csproj
new file mode 100644
index 0000000..7ee4ecc
--- /dev/null
+++ b/FileServer/Web/Web.csproj
@@ -0,0 +1,311 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.Default.props')" />
+ <Import Project="..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props" Condition="Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" />
+ <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>
+ </ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{18878028-6360-4299-88FC-2A3B3A45E3A8}</ProjectGuid>
+ <ProjectTypeGuids>{349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc}</ProjectTypeGuids>
+ <OutputType>Library</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>Web</RootNamespace>
+ <AssemblyName>Web</AssemblyName>
+ <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>
+ <MvcBuildViews>false</MvcBuildViews>
+ <UseIISExpress>true</UseIISExpress>
+ <Use64BitIISExpress />
+ <IISExpressSSLPort />
+ <IISExpressAnonymousAuthentication />
+ <IISExpressWindowsAuthentication />
+ <IISExpressUseClassicPipelineMode />
+ <UseGlobalApplicationHostFile />
+ <NuGetPackageImportStamp>
+ </NuGetPackageImportStamp>
+ <TargetFrameworkProfile />
+ <TypeScriptToolsVersion>3.1</TypeScriptToolsVersion>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll</HintPath>
+ </Reference>
+ <Reference Include="EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
+ <HintPath>..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.AspNet.TelemetryCorrelation, Version=1.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.AspNet.TelemetryCorrelation.1.0.5\lib\net45\Microsoft.AspNet.TelemetryCorrelation.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=2.0.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\lib\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll</HintPath>
+ </Reference>
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
+ <HintPath>..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll</HintPath>
+ </Reference>
+ <Reference Include="Quartz, Version=3.0.7.0, Culture=neutral, PublicKeyToken=f6b8c98a402cc8a4, processorArchitecture=MSIL">
+ <HintPath>..\packages\Quartz.3.0.7\lib\net452\Quartz.dll</HintPath>
+ </Reference>
+ <Reference Include="System" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.3.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
+ <HintPath>..\packages\System.Diagnostics.DiagnosticSource.4.5.1\lib\net45\System.Diagnostics.DiagnosticSource.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Drawing" />
+ <Reference Include="System.Net.Http.Formatting, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Numerics" />
+ <Reference Include="System.Runtime.Remoting" />
+ <Reference Include="System.Web.DynamicData" />
+ <Reference Include="System.Web.Entity" />
+ <Reference Include="System.Web.ApplicationServices" />
+ <Reference Include="System.ComponentModel.DataAnnotations" />
+ <Reference Include="System.Web.Extensions" />
+ <Reference Include="System.Web" />
+ <Reference Include="System.Web.Abstractions" />
+ <Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.Http, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.Http.WebHost, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.7\lib\net45\System.Web.Http.WebHost.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.Mvc, Version=5.2.7.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.AspNet.Mvc.5.2.7\lib\net45\System.Web.Mvc.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.Routing" />
+ <Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <HintPath>..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Configuration" />
+ <Reference Include="System.Web.Services" />
+ <Reference Include="System.EnterpriseServices" />
+ <Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+ <Private>True</Private>
+ <HintPath>..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Net.Http">
+ </Reference>
+ <Reference Include="System.Net.Http.WebRequest">
+ </Reference>
+ <Reference Include="System.Web.Optimization">
+ <HintPath>..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll</HintPath>
+ </Reference>
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="WebGrease">
+ <Private>True</Private>
+ <HintPath>..\packages\WebGrease.1.6.0\lib\WebGrease.dll</HintPath>
+ </Reference>
+ <Reference Include="Antlr3.Runtime">
+ <Private>True</Private>
+ <HintPath>..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="App_Start\BundleConfig.cs" />
+ <Compile Include="App_Start\FilterConfig.cs" />
+ <Compile Include="App_Start\RouteConfig.cs" />
+ <Compile Include="App_Start\WebApiConfig.cs" />
+ <Compile Include="BackgroundWorkers\GarbageUploadsWorker.cs" />
+ <Compile Include="Controllers\Base\BaseController.cs" />
+ <Compile Include="Controllers\API\ExplorerController.cs" />
+ <Compile Include="Controllers\HomeController.cs" />
+ <Compile Include="Controllers\API\UploadFilesController.cs" />
+ <Compile Include="Controllers\API\UserController.cs" />
+ <Compile Include="Global.asax.cs">
+ <DependentUpon>Global.asax</DependentUpon>
+ </Compile>
+ <Compile Include="Models\Base\BaseApiResult.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <Content Include="Content\bootstrap-grid.css" />
+ <Content Include="Content\bootstrap-grid.min.css" />
+ <Content Include="Content\bootstrap-reboot.css" />
+ <Content Include="Content\bootstrap-reboot.min.css" />
+ <Content Include="Content\bootstrap.css" />
+ <Content Include="Content\bootstrap.min.css" />
+ <Content Include="favicon.ico" />
+ <Content Include="Global.asax" />
+ <Content Include="Content\Site.css" />
+ <Content Include="Content\bootstrap.min.css.map" />
+ <Content Include="Content\bootstrap.css.map" />
+ <Content Include="Content\bootstrap-reboot.min.css.map" />
+ <Content Include="Content\bootstrap-reboot.css.map" />
+ <Content Include="Content\bootstrap-grid.min.css.map" />
+ <Content Include="Content\bootstrap-grid.css.map" />
+ <None Include="Properties\PublishProfiles\FolderProfile.pubxml" />
+ <Content Include="Scripts\bootstrap.bundle.js" />
+ <Content Include="Scripts\bootstrap.bundle.min.js" />
+ <Content Include="Scripts\bootstrap.js" />
+ <Content Include="Scripts\bootstrap.min.js" />
+ <Content Include="Scripts\bootstrap.min.js.map" />
+ <Content Include="Scripts\bootstrap.js.map" />
+ <Content Include="Scripts\bootstrap.bundle.min.js.map" />
+ <Content Include="Scripts\bootstrap.bundle.js.map" />
+ <Content Include="Scripts\esm\popper-utils.js" />
+ <Content Include="Scripts\esm\popper-utils.min.js" />
+ <Content Include="Scripts\esm\popper.js" />
+ <Content Include="Scripts\esm\popper.min.js" />
+ <Content Include="Scripts\esm\popper.min.js.map" />
+ <Content Include="Scripts\esm\popper.js.map" />
+ <Content Include="Scripts\esm\popper-utils.min.js.map" />
+ <Content Include="Scripts\esm\popper-utils.js.map" />
+ <None Include="Scripts\jquery-3.4.1.intellisense.js" />
+ <Content Include="Scripts\jquery-3.4.1.js" />
+ <Content Include="Scripts\jquery-3.4.1.min.js" />
+ <Content Include="Scripts\jquery-3.4.1.slim.js" />
+ <Content Include="Scripts\jquery-3.4.1.slim.min.js" />
+ <Content Include="Scripts\jquery-3.4.1.slim.min.map" />
+ <Content Include="Scripts\jquery-3.4.1.min.map" />
+ <None Include="Scripts\jquery.validate-vsdoc.js" />
+ <Content Include="Scripts\jquery.validate.js" />
+ <Content Include="Scripts\jquery.validate.min.js" />
+ <Content Include="Scripts\jquery.validate.unobtrusive.js" />
+ <Content Include="Scripts\jquery.validate.unobtrusive.min.js" />
+ <Content Include="Scripts\React\BootstrapControl.jsx" />
+ <Content Include="Scripts\React\ExplorerActionsControl.jsx" />
+ <Content Include="Scripts\Services\FileExplorerServices.js" />
+ <Content Include="Scripts\Services\UserServices.js" />
+ <Content Include="Scripts\modernizr-2.8.3.js" />
+ <Content Include="Scripts\popper-utils.js" />
+ <Content Include="Scripts\popper-utils.min.js" />
+ <Content Include="Scripts\popper.js" />
+ <Content Include="Scripts\popper.min.js" />
+ <Content Include="Scripts\React\App.jsx" />
+ <Content Include="Scripts\React\FileExplorerControl.jsx" />
+ <Content Include="Scripts\React\FileExplorerRow.jsx" />
+ <Content Include="Scripts\React\RouteSystem.jsx" />
+ <Content Include="Scripts\React\UploaderControl.jsx" />
+ <Content Include="Scripts\React\UserControl.jsx" />
+ <Content Include="Scripts\Services\UploadServices.js" />
+ <Content Include="Scripts\Tools\Sort.js" />
+ <Content Include="Scripts\umd\popper-utils.js" />
+ <Content Include="Scripts\umd\popper-utils.min.js" />
+ <Content Include="Scripts\umd\popper.js" />
+ <Content Include="Scripts\umd\popper.min.js" />
+ <Content Include="Web.config">
+ <SubType>Designer</SubType>
+ </Content>
+ <Content Include="Web.Debug.config">
+ <DependentUpon>Web.config</DependentUpon>
+ </Content>
+ <Content Include="Web.Release.config">
+ <DependentUpon>Web.config</DependentUpon>
+ </Content>
+ <Content Include="Views\Web.config" />
+ <Content Include="Views\_ViewStart.cshtml" />
+ <Content Include="Views\Shared\Error.cshtml" />
+ <Content Include="Views\Shared\_Layout.cshtml" />
+ <Content Include="Views\Home\About.cshtml" />
+ <Content Include="Views\Home\Contact.cshtml" />
+ <Content Include="Views\Home\Index.cshtml" />
+ <Content Include="Scripts\umd\popper.min.js.map" />
+ <Content Include="Scripts\umd\popper.js.map" />
+ <Content Include="Scripts\umd\popper-utils.min.js.map" />
+ <Content Include="Scripts\umd\popper-utils.js.map" />
+ <Content Include="Scripts\README.md" />
+ <Content Include="Scripts\popper.min.js.map" />
+ <Content Include="Scripts\popper.js.map" />
+ <Content Include="Scripts\popper-utils.min.js.map" />
+ <Content Include="Scripts\popper-utils.js.map" />
+ </ItemGroup>
+ <ItemGroup>
+ <Folder Include="App_Data\" />
+ </ItemGroup>
+ <ItemGroup>
+ <None Include="packages.config" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\BLL\BLL.csproj">
+ <Project>{b03d6843-e0cd-4526-990d-0300e8b148ec}</Project>
+ <Name>BLL</Name>
+ </ProjectReference>
+ <ProjectReference Include="..\Model\Model.csproj">
+ <Project>{156c9263-5079-445d-b579-3540ca1b54b1}</Project>
+ <Name>Model</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <ItemGroup>
+ <Service Include="{4A0DDDB5-7A95-4FBF-97CC-616D07737A77}" />
+ </ItemGroup>
+ <ItemGroup>
+ <TypeScriptCompile Include="Scripts\index.d.ts" />
+ </ItemGroup>
+ <PropertyGroup>
+ <VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
+ <VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
+ </PropertyGroup>
+ <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets" Condition="Exists('$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TypeScript\Microsoft.TypeScript.targets')" />
+ <Import Project="$(VSToolsPath)\WebApplications\Microsoft.WebApplication.targets" Condition="'$(VSToolsPath)' != ''" />
+ <Import Project="$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v10.0\WebApplications\Microsoft.WebApplication.targets" Condition="false" />
+ <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'">
+ <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" />
+ </Target>
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <UseIIS>True</UseIIS>
+ <AutoAssignPort>True</AutoAssignPort>
+ <DevelopmentServerPort>48309</DevelopmentServerPort>
+ <DevelopmentServerVPath>/</DevelopmentServerVPath>
+ <IISUrl>http://localhost:47780/</IISUrl>
+ <NTLMAuthentication>False</NTLMAuthentication>
+ <UseCustomServer>False</UseCustomServer>
+ <CustomServerUrl>
+ </CustomServerUrl>
+ <SaveServerSettingsInUserFile>False</SaveServerSettingsInUserFile>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+ <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
+ <PropertyGroup>
+ <ErrorText>Данный проект ссылается на пакеты NuGet, отсутствующие на этом компьютере. Используйте восстановление пакетов NuGet, чтобы скачать их. Дополнительную информацию см. по адресу: http://go.microsoft.com/fwlink/?LinkID=322105. Отсутствует следующий файл: {0}.</ErrorText>
+ </PropertyGroup>
+ <Error Condition="!Exists('..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.2.0.1\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
+ </Target>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target> -->
+</Project>
\ No newline at end of file
FileServer/Web/Web.csproj.user 49(+49 -0)
diff --git a/FileServer/Web/Web.csproj.user b/FileServer/Web/Web.csproj.user
new file mode 100644
index 0000000..83e7a47
--- /dev/null
+++ b/FileServer/Web/Web.csproj.user
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <UseIISExpress>true</UseIISExpress>
+ <Use64BitIISExpress />
+ <IISExpressSSLPort />
+ <IISExpressAnonymousAuthentication />
+ <IISExpressWindowsAuthentication />
+ <IISExpressUseClassicPipelineMode />
+ <UseGlobalApplicationHostFile />
+ <LastActiveSolutionConfig>Debug|Any CPU</LastActiveSolutionConfig>
+ <Controller_SelectedScaffolderID>MvcControllerEmptyScaffolder</Controller_SelectedScaffolderID>
+ <Controller_SelectedScaffolderCategoryPath>root/Controller</Controller_SelectedScaffolderCategoryPath>
+ <WebStackScaffolding_ControllerDialogWidth>600</WebStackScaffolding_ControllerDialogWidth>
+ <WebStackScaffolding_IsLayoutPageSelected>True</WebStackScaffolding_IsLayoutPageSelected>
+ <WebStackScaffolding_IsPartialViewSelected>False</WebStackScaffolding_IsPartialViewSelected>
+ <WebStackScaffolding_IsReferencingScriptLibrariesSelected>False</WebStackScaffolding_IsReferencingScriptLibrariesSelected>
+ <WebStackScaffolding_LayoutPageFile />
+ <WebStackScaffolding_IsAsyncSelected>False</WebStackScaffolding_IsAsyncSelected>
+ <WebStackScaffolding_ViewDialogWidth>600</WebStackScaffolding_ViewDialogWidth>
+ <NameOfLastUsedPublishProfile>FolderProfile</NameOfLastUsedPublishProfile>
+ <ProjectView>ProjectFiles</ProjectView>
+ </PropertyGroup>
+ <ProjectExtensions>
+ <VisualStudio>
+ <FlavorProperties GUID="{349c5851-65df-11da-9384-00065b846f21}">
+ <WebProjectProperties>
+ <StartPageUrl>
+ </StartPageUrl>
+ <StartAction>SpecificPage</StartAction>
+ <AspNetDebugging>True</AspNetDebugging>
+ <SilverlightDebugging>False</SilverlightDebugging>
+ <NativeDebugging>False</NativeDebugging>
+ <SQLDebugging>False</SQLDebugging>
+ <ExternalProgram>
+ </ExternalProgram>
+ <StartExternalURL>
+ </StartExternalURL>
+ <StartCmdLineArguments>
+ </StartCmdLineArguments>
+ <StartWorkingDirectory>
+ </StartWorkingDirectory>
+ <EnableENC>True</EnableENC>
+ <AlwaysStartWebServerOnDebug>True</AlwaysStartWebServerOnDebug>
+ </WebProjectProperties>
+ </FlavorProperties>
+ </VisualStudio>
+ </ProjectExtensions>
+</Project>
\ No newline at end of file
FileServer/Web/Web.Debug.config 30(+30 -0)
diff --git a/FileServer/Web/Web.Debug.config b/FileServer/Web/Web.Debug.config
new file mode 100644
index 0000000..c50daa5
--- /dev/null
+++ b/FileServer/Web/Web.Debug.config
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Дополнительные сведения об использовании преобразования Web.config см. на странице https://go.microsoft.com/fwlink/?LinkId=301874-->
+
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+ <!--
+ В следующем примере преобразование "SetAttributes" будет изменять значение
+ "connectionString" с целью использования "ReleaseSQLServer", только когда
+ указатель "Match" находит атрибут "name", который имеет значение "MyDB".
+
+ <connectionStrings>
+ <add name="MyDB"
+ connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
+ xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+ </connectionStrings>
+ -->
+ <system.web>
+ <!--
+ В следующем примере преобразование "Replace" будет заменять весь
+ раздел <customErrors> в файле Web.config.
+ Заметьте, поскольку имеется только один раздел customErrors в узле
+ <system.web>, не требуется использовать атрибут "xdt:Locator".
+
+ <customErrors defaultRedirect="GenericError.htm"
+ mode="RemoteOnly" xdt:Transform="Replace">
+ <error statusCode="500" redirect="InternalError.htm"/>
+ </customErrors>
+ -->
+ </system.web>
+</configuration>
FileServer/Web/Web.Release.config 31(+31 -0)
diff --git a/FileServer/Web/Web.Release.config b/FileServer/Web/Web.Release.config
new file mode 100644
index 0000000..54aa209
--- /dev/null
+++ b/FileServer/Web/Web.Release.config
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!-- Дополнительные сведения об использовании преобразования Web.config см. на странице https://go.microsoft.com/fwlink/?LinkId=301874-->
+
+<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
+ <!--
+ В следующем примере преобразование "SetAttributes" будет изменять значение
+ "connectionString" с целью использования "ReleaseSQLServer", только когда
+ указатель "Match" находит атрибут "name", который имеет значение "MyDB".
+
+ <connectionStrings>
+ <add name="MyDB"
+ connectionString="Data Source=ReleaseSQLServer;Initial Catalog=MyReleaseDB;Integrated Security=True"
+ xdt:Transform="SetAttributes" xdt:Locator="Match(name)"/>
+ </connectionStrings>
+ -->
+ <system.web>
+ <compilation xdt:Transform="RemoveAttributes(debug)" />
+ <!--
+ В следующем примере преобразование "Replace" будет заменять весь
+ раздел <customErrors> в файле Web.config.
+ Заметьте, поскольку имеется только один раздел customErrors в узле
+ <system.web>, не требуется использовать атрибут "xdt:Locator".
+
+ <customErrors defaultRedirect="GenericError.htm"
+ mode="RemoteOnly" xdt:Transform="Replace">
+ <error statusCode="500" redirect="InternalError.htm"/>
+ </customErrors>
+ -->
+ </system.web>
+</configuration>