Раздел управления файлами для панели администратора

Я разрабатываю веб-приложение CRM для моего клиента. Включает управление клиентами, платежи и так далее.

Технологии, которые я использую:

  • ASP.NET MVC 5
  • EntityFramework 6
  • .NET Framework 4.5.2
  • Bootstrap 3

Теперь мой клиент хочет добавить облачное хранилище файлов, такое как Dropbox, в веб-приложение. Он должен позволять загружать / удалять файлы и папки (для администраторов), а обычные пользователи должны иметь возможность их скачивать.

Я думаю, что есть несколько хороших законченных решений для этого, поэтому я не изобретаю колесо. Opensource и Free являются предпочтительными. Я ищу модуль, который я мог бы просто установить и добавить в свое существующее приложение.


ОБНОВИТЬ

Я думаю, что Сообщество понял меня неправильно. Я не ищу действительно тяжелое решение для управления файлами. Нужно что-то вроде предложенного Масудом Бимаром. Но я ищу что-то еще меньше и проще.

Я просто не хочу изобретать велосипед, и мне скучно писать код с нуля.

Я уверен, что кто-то уже разработал эту функциональность.

Опять же, решение должно просто позволить:

  • Загрузить файл в локальную папку
  • Удалить файлы из локальной папки
  • Создать папки в локальной папке
  • Удалить папки в локальной папке

Мой клиент будет использовать его время от времени и будет загружать не более 20 файлов. Может быть, удалить их и загружать новые время от времени. Вот и все.

3 ответа

Решение

Ниже приведен пример простой системы управления файлами, использующей стандартные контроллеры и действия ASP.NET MVC, инфраструктуру сущностей и потрясающую зону поддержки библиотеки javascript для загрузки нескольких файлов с использованием AJAX.

У каждого клиента будет список файлов, поэтому нам нужно сохранить эту информацию в таблице базы данных, вот модель:

public class FileUpload
{
    public int Id { get; set; }
    public int CustomerId { get; set; }
    public string Filename { get; set; }
    public string OriginalFilename { get; set; }
    public string ContentType { get; set; }
}

Затем контроллер будет обрабатывать загрузки и выгрузки файлов и т. Д.

public class FileUploadController : Controller
{
    private SomeDbContext db = new SomeDbContext();

    // You should store the following settings in your Web.config or in your DB, I just put them here for demo purposes

    // This is the root folder where your files will be saved
    private string FilesRoot = @"c:\temp";

    // Accepted file types and maximum size, for security (it should match the settings in your view)
    private string[] AcceptedFiles = new string[] { ".jpg", ".png", ".doc" };
    private int MaxFileSizeMB = 10;

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult UploadFiles(int customerId)
    {
        foreach(string file in Request.Files)
        {
            var upload = Request.Files[file];

            if (!ValidateUpload(upload))
                return new HttpStatusCodeResult(HttpStatusCode.Forbidden);

            string filename = Guid.NewGuid().ToString() + Path.GetExtension(upload.FileName);

            // Save the file in FilesRoot/{CustomerId}/{GUID}
            string savePath = Path.Combine(FilesRoot, customerId.ToString());
            if (!Directory.Exists(savePath))
            {
                Directory.CreateDirectory(savePath);
            }

            upload.SaveAs(Path.Combine(savePath, filename));

            // Save file info to database
            var fileUpload = new FileUploadModel()
            {
                CustomerId = customerId,
                Filename = filename,
                OriginalFilename = upload.FileName,
                ContentType = upload.ContentType
            };

            db.FileUploads.Add(fileUpload);
            db.SaveChanges();
        }

        return new HttpStatusCodeResult(HttpStatusCode.OK);
    }

    private bool ValidateUpload(HttpPostedFileBase upload)
    {
        if (!AcceptedFiles.Contains(Path.GetExtension(upload.FileName)))
            return false;
        else if (upload.ContentLength > MaxFileSizeMB * 1048576)
            return false;

        return true;
    }

    public ActionResult DownloadFile(int id)
    {
        var fileUpload = db.FileUploads.FirstOrDefault(x => x.Id == id);
        if (fileUpload == null)
        {
            return new HttpStatusCodeResult(HttpStatusCode.NotFound);
        }

        string path = Path.Combine(FilesRoot, fileUpload.CustomerId.ToString(), fileUpload.Filename);

        byte[] fileContents = System.IO.File.ReadAllBytes(path);

        return File(fileContents, fileUpload.ContentType, fileUpload.OriginalFilename);
    }

    public ActionResult ListFiles(int customerId)
    {
        var files = db.FileUploads.Where(x => x.CustomerId == customerId);
        return View(files.ToList());
    }


    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }
}

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

@{
    ViewBag.Title = "Upload Files";
}

<div>
    <button id="selectFile">Click to Browse File</button>
</div>

@using (Html.BeginForm("UploadFiles", "FileUpload", FormMethod.Post, new { id = "uploadForm", @class = "dropzone dropzone-area" }))
{
    @Html.AntiForgeryToken()

    @Html.Hidden("CustomerId", 1)

    <div class="dz-message">Drop File Here To Upload</div>

    <div class="fallback">
        <input name="file" type="file" multiple />
    </div>
}


@section Scripts {
    <script src="@Url.Content("~/Scripts/dropzone.js")"></script>

    <script type="text/javascript">
        Dropzone.options.selectForm = {
            paramName: 'file',
            maxFilesize: 10,
            maxFiles: 10,
            acceptedFiles: '.jpg,.png,.doc,.pdf',
            addRemoveLinks: false
        };

        $('#selectFile').on('click', function () {
            $('#uploadForm').trigger('click');
        });
    </script>
}

На самом деле изобретать велосипед сложно, однако использование сторонних пакетов всегда будет иметь свои ограничения.

Я использую Bucket S3 в Amazon Web Services, и поскольку доступ к файлам осуществляется через учетные данные, вы можете легко ограничить доступ к файлу, записав в базу данных при загрузке пользователей, которые имеют доступ.

Вот пример загрузки и скачивания кода.

Вам нужно будет установить пакет AWS SDK Nuget.

https://aws.amazon.com/sdk-for-net/

Ссылка с объяснением для создания учетных данных

https://docs.aws.amazon.com/en/sdk-for-net/v2/developer-guide/net-dg-setup.html

Я надеюсь, что это может помочь

using Amazon.S3;
using Amazon.S3.Model;

public async Task<IActionResult> Upload(IFormFile file)
{
    BasicAWSCredentials awsCredentials = new BasicAWSCredentials("accessKey", "secretKey");
    IAmazonS3 clientAws = new AmazonS3Client(awsCredentials, Amazon.RegionEndpoint.EUCentral1);
    string urlTemp = Path.GetTempFileName();
    string extension = Path.GetExtension(file.FileName);
    Guid guid = Guid.NewGuid();
    string nameFile = guid + extension;
    string contentType = file.ContentType;

    using (var fileStream = new FileStream(urlTemp, FileMode.Create))
    {
        await file.CopyToAsync(fileStream);
    }

    try
    {
        // simple object put
        using (clientAws)
        {
            var request = new PutObjectRequest()
            {
                BucketName = "yourbucket",
                Key = nameFile,
                FilePath = urlTemp,
                ContentType = contentType
            };
            var response = await clientAws.PutObjectAsync(request);

            //write in your db
        }
    }
    catch (AmazonS3Exception amazonS3Exception)
    {
        if (amazonS3Exception.ErrorCode != null &&
            (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") ||
            amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
        {
            Console.WriteLine("Please check the provided AWS Credentials.");
            Console.WriteLine("If you haven't signed up for Amazon S3, please visit http://aws.amazon.com/s3");
        }
        else
        {
            Console.WriteLine("An error occurred with the message '{0}' when writing an object", amazonS3Exception.Message);
        }
    }

    return Ok();
}

public async Task<IActionResult> Download(string file)
{
    try
    {
        BasicAWSCredentials awsCredentials = new BasicAWSCredentials("accessKey", "secretKey");
        IAmazonS3 clientAws = new AmazonS3Client(awsCredentials, Amazon.RegionEndpoint.EUCentral1);

        GetObjectResponse response = new GetObjectResponse();

        string urlTemp = Path.GetTempPath();
        Guid guid = Guid.NewGuid();
        string nameFile = guid + ".pdf";

        try
        {
            // simple object put
            using (clientAws)
            {
                GetObjectRequest request = new GetObjectRequest();

                request.BucketName = "yourBucket";
                request.Key = file;
                response = await clientAws.GetObjectAsync(request);
                CancellationTokenSource source = new CancellationTokenSource();
                CancellationToken token = source.Token;
                await response.WriteResponseStreamToFileAsync(urlTemp + nameFile, true, token);


                var path = urlTemp + nameFile;
                var memory = new MemoryStream();
                using (var stream = new FileStream(path, FileMode.Open))
                {
                    await stream.CopyToAsync(memory);
                }
                memory.Position = 0;

                var fsResult = new FileStreamResult(memory, "application/pdf");
                return fsResult;

            }

        }
        catch (AmazonS3Exception amazonS3Exception)
        {
            if (amazonS3Exception.ErrorCode != null &&
                (amazonS3Exception.ErrorCode.Equals("InvalidAccessKeyId") ||
                amazonS3Exception.ErrorCode.Equals("InvalidSecurity")))
            {
                Console.WriteLine("Please check the provided AWS Credentials.");
                Console.WriteLine("If you haven't signed up for Amazon S3, please visit http://aws.amazon.com/s3");
            }
            else
            {
                Console.WriteLine("An error occurred with the message '{0}' when writing an object", amazonS3Exception.Message);
            }

        }
    }
    catch (Exception ex)
    {
        //throw;
    }

    return View();
}

Я использовал этот, построенный с библиотекой elFinder.

Файловый менеджер, с ELFinder.Net. Поддержка каталогов, PDF-файлов, разрешений, Nice UI.

Я был полностью удовлетворен этим.

Информация о пакетах:

  <package id="bootstrap" version="3.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net45" />

GitHub хранилище

Другие вопросы по тегам