Раздел управления файлами для панели администратора
Я разрабатываю веб-приложение 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" />