Commit fe409d4b authored by SergeevaAA's avatar SergeevaAA

Реализовано удаление файлов и проверка на существование при скачивании.

parent 422cd4bf
......@@ -81,26 +81,6 @@
.ToList();
}
/// <summary>
/// Получение списка файлов
/// </summary>
/// <returns>Запрос на получение списка файлов</returns>
public IQueryable<FileViewModel> GetAll()
{
return _db.Files.Include(f => f.User).OrderByDescending(f => f.UploadDateTime)
.Select(f => new FileViewModel
{
Id = f.Id,
Name = f.Name,
Description = f.Description,
UploadDateTime = f.UploadDateTime,
Size = GetSize(f.Size),
Format = f.Format.ToString(),
FormatDisplayName = f.Format.GetDisplayName(),
User = f.User.Login
});
}
/// <summary>
/// Скачивание файла
/// </summary>
......@@ -111,14 +91,18 @@
{
var file = _db.Files.FirstOrDefault(f => f.Id == id);
_db.Actions.Add(new Action
if (file != null)
{
FileId = id,
UserId = userId,
ActionType = ActionType.Download
});
_db.Actions.Add(new Action
{
FileId = id,
UserId = userId,
DateTime = DateTime.Now,
ActionType = ActionType.Download
});
_db.SaveChanges();
_db.SaveChanges();
}
return new FileResultViewModel
{
......@@ -128,6 +112,19 @@
};
}
/// <summary>
/// Удаление файла
/// </summary>
/// <param name="id">Идентификатор файла</param>
public void Delete(long id)
{
var file = _db.Files.FirstOrDefault(f => f.Id == id);
_db.Files.Remove(file);
_db.SaveChanges();
}
/// <summary>
/// Загрузка файла
/// </summary>
......@@ -161,6 +158,16 @@
_db.SaveChanges();
}
/// <summary>
/// Проверка существования файла
/// </summary>
/// <param name="id">Идентификатор файла</param>
/// <returns>Существует ли файл</returns>
public bool IsExist(long id)
{
return _db.Files.FirstOrDefault(f => f.Id == id) != null;
}
/// <summary>
/// Получение формата файла
/// </summary>
......
namespace FileDesk.Services.Interfaces
{
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using FileDesk.Domain.ViewModels;
......@@ -33,5 +31,18 @@
/// <param name="id">Идентификатор пользователя</param>
/// <returns>Файл</returns>
FileResultViewModel Download(long id, long userId);
/// <summary>
/// Удаление файла
/// </summary>
/// <param name="id">Идентификатор файла</param>
void Delete(long id);
/// <summary>
/// Проверка существования файла
/// </summary>
/// <param name="id">Идентификатор файла</param>
/// <returns>Существует ли файл</returns>
bool IsExist(long id);
}
}
\ No newline at end of file
namespace FileDesk.Web.Controllers
{
using System.Threading.Tasks;
using System;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
......@@ -8,7 +8,7 @@
using FileDesk.Services.Interfaces;
using FileDesk.Domain.ViewModels;
using System;
using FileDesk.Web.Helpers;
/// <summary>
/// Контроллер для работы с файлами
......@@ -46,7 +46,14 @@
[HttpGet]
public IActionResult Index()
{
return View();
try
{
return View();
}
catch (Exception ex)
{
return PartialView("Error", ExceptionHelper.GetMessage(ex));
}
}
/// <summary>
......@@ -65,12 +72,37 @@
return PartialView("_Search", model);
}
catch (Exception)
catch (Exception ex)
{
return BadRequest(ExceptionHelper.GetMessage(ex));
}
}
/// <summary>
/// Удаление файла
/// </summary>
/// <param name="id">Идентификатор файла</param>
/// <returns></returns>
[Authorize(Roles = "admin, user")]
[HttpGet]
public ActionResult Delete(long id)
{
try
{
// handle exception
_fileService.Delete(id);
return Ok($"Файл был успешно удален.");
}
catch (Exception ex)
{
if (ex.GetType() == typeof(ArgumentNullException))
{
return BadRequest($"Не удалось удалить файл. Файл не был найден.");
}
return PartialView("Error");
return BadRequest($"Не удалось удалить файл. При попытке удаления произошла ошибка: {ExceptionHelper.GetMessage(ex)}");
}
}
/// <summary>
......@@ -81,7 +113,14 @@
[HttpGet]
public IActionResult Upload()
{
return View();
try
{
return View();
}
catch (Exception ex)
{
return PartialView("Error", ExceptionHelper.GetMessage(ex));
}
}
/// <summary>
......@@ -92,20 +131,45 @@
[Authorize(Roles = "admin, user")]
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Upload(UploadViewModel model)
public IActionResult Upload(UploadViewModel model)
{
if (ModelState.IsValid)
try
{
var userId = _userService.GetId(HttpContext.User.Identity.Name);
if (ModelState.IsValid)
{
var userId = _userService.GetId(HttpContext.User.Identity.Name);
_fileService.Upload(userId, model);
_fileService.Upload(userId, model);
return RedirectToAction("Index", "File");
}
return RedirectToAction("Index", "File");
}
return View(model);
return View(model);
}
catch (Exception ex)
{
return View("Error", $"Не удалось загрузить файл. При попытке загрузки произошла ошибка: {ExceptionHelper.GetMessage(ex)}");
}
}
/// <summary>
/// проверка существования файла
/// </summary>
/// <param name="id">Идентификатор файла</param>
/// <returns>Существует ли файл</returns>
[Authorize(Roles = "admin, user")]
[HttpGet]
public ActionResult IsExist(long id)
{
if (_fileService.IsExist(id))
{
return Ok();
}
else
{
return BadRequest("Не удалось скачать файл. Файл не был найден.");
}
}
/// <summary>
/// Скачивание файла
......@@ -114,12 +178,24 @@
/// <returns>Файл</returns>
[Authorize(Roles = "admin, user")]
[HttpGet]
public FileResult Download(long id)
public ActionResult Download(long id)
{
var userId = _userService.GetId(HttpContext.User.Identity.Name);
var file = _fileService.Download(id, userId);
try
{
var userId = _userService.GetId(HttpContext.User.Identity.Name);
var file = _fileService.Download(id, userId);
return File(file.Content, file.ContentType, file.Name);
}
catch (Exception ex)
{
if (ex.GetType() == typeof(NullReferenceException))
{
return BadRequest($"Не удалось скачать файл. Файл не был найден.");
}
return File(file.Content, file.ContentType, file.Name);
return BadRequest($"Не удалось скачать файл. При попытке скачивания произошла ошибка: {ExceptionHelper.GetMessage(ex)}");
}
}
#endregion
......
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
using System.Diagnostics;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using FileDesk.Web.Models;
using FileDesk.Services;
using Microsoft.AspNetCore.Authorization;
namespace FileDesk.Web.Controllers
{
......@@ -40,7 +35,7 @@ namespace FileDesk.Web.Controllers
[ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)]
public IActionResult Error()
{
return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier });
return View();
}
}
}
......@@ -9,6 +9,9 @@ using System.Threading.Tasks;
namespace Microsoft.AspNetCore.Mvc.Rendering
{
/// <summary>
/// Расширение для работы с хелперами Html
/// </summary>
public static class HtmlHelperViewExtensions
{
public static IHtmlContent Action(this IHtmlHelper helper, string action, object parameters = null)
......
namespace FileDesk.Web.Helpers
{
using System;
/// <summary>
/// Хелпер для работы с исключениями
/// </summary>
public static class ExceptionHelper
{
/// <summary>
/// Получение полного списка сообщений об исключениях
/// </summary>
/// <param name="exception"></param>
/// <returns></returns>
public static string GetMessage(Exception exception)
{
if (exception == null)
{
return string.Empty;
}
var message = exception.Message;
while (exception.InnerException != null)
{
message += "\n\n" + exception.InnerException.Message;
exception = exception.InnerException;
}
return message;
}
}
}
\ No newline at end of file
namespace FileDesk.Web.Models
{
public class ErrorViewModel
{
public string RequestId { get; set; }
public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
}
}
\ No newline at end of file
......@@ -4,7 +4,7 @@
<br />
Поиск по описанию:
<input type="search" id="searchString" placeholder="Введите слова для поиска через пробел и нажмите Enter" onsearch="search()" />
<input type="search" id="searchString" placeholder="Введите слова для поиска через пробел и нажмите Enter" onsearch="searchFiles()" />
<br />
<input type="checkbox" id="isCaseSensitive" /> Учитывать регистр
......@@ -13,9 +13,14 @@
</div>
<script>
function search() {
$.get('@Url.Action("Search", "File")', { searchString: $('#searchString').val(), isCaseSensitive: $('#isCaseSensitive')[0].checked }, function (data) {
$('#search-results').replaceWith(data);
});
function searchFiles() {
$.get('@Url.Action("Search", "File")', { searchString: $('#searchString').val(), isCaseSensitive: $('#isCaseSensitive')[0].checked })
.done(function (data) {
$('#search-results').html(data);
})
.fail(function (xhr, status, error) {
$('#search-results').html(xhr.responseText);
})
}
</script>
\ No newline at end of file
@model ErrorViewModel
@model string
@{
ViewData["Title"] = "Error";
ViewData["Title"] = "Ошибка";
}
<h1 class="text-danger">Ошибка</h1>
<h2 class="text-danger">Во время обработки Вашего запроса произошла ошибка. Сообщите о ней <a asp-area="" asp-controller="Home" asp-action="Contacts">разработчику</a></h2>
<h2>Во время обработки Вашего запроса произошла ошибка. Сообщите о ней <a asp-area="" asp-controller="Home" asp-action="Contacts">разработчику</a></h2>
@if (Model.ShowRequestId)
@if (!string.IsNullOrEmpty(Model))
{
<p>
<strong>Request ID:</strong> <code>@Model.RequestId</code>
</p>
}
<h3>Development Mode</h3>
<p>
Swapping to <strong>Development</strong> environment will display more detailed information about the error that occurred.
<strong class="text-danger">Текст ошибки: </strong>
<code>@Model</code>
</p>
<p>
<strong>The Development environment shouldn't be enabled for deployed applications.</strong>
It can result in displaying sensitive information from exceptions to end users.
For local debugging, enable the <strong>Development</strong> environment by setting the <strong>ASPNETCORE_ENVIRONMENT</strong> environment variable to <strong>Development</strong>
and restarting the app.
</p>
\ No newline at end of file
}
\ No newline at end of file
@model List<FileDesk.Domain.ViewModels.FileViewModel>
<div id="search-results">
<div id="results">
@if (Model != null && Model.Any())
{
<table class="table">
<tr>
<th></th>
<th>Название</th>
<th>Размер</th>
<th>Дата добавления</th>
<th>Пользователь</th>
<th>Описание</th>
<th>Действия</th>
</tr>
@foreach (var file in Model)
{
<table class="table">
<tr>
<td>
<input hidden asp-for="@file.Id" />
<img src="~/images/@String.Format("{0}.png", file.Format)" title="@file.FormatDisplayName" />
</td>
<td><a asp-area="" asp-controller="File" asp-action="Download" asp-route-id="@file.Id" target="_blank">@file.Name</a></td>
<td><input asp-for="@file.Size" /></td>
<td><input asp-for="@file.UploadDateTime" /></td>
<td><input asp-for="@file.User" /></td>
<td><input asp-for="@file.Description" /></td>
<td><button type="submit" class="download" onclick="window.location.href='@Url.Action("Download", "File", new { id = file.Id }, Context.Request.Scheme)'" title="Скачать файл" /></td>
<th></th>
<th>Название</th>
<th>Размер</th>
<th>Дата добавления</th>
<th>Пользователь</th>
<th>Описание</th>
<th>Действия</th>
</tr>
}
</table>
@foreach (var file in Model)
{
<tr>
<td>
<input hidden asp-for="@file.Id" />
<img src="~/images/@String.Format("{0}.png", file.Format)" title="@file.FormatDisplayName" />
</td>
<td><input asp-for="@file.Name" /></td>
<td><input asp-for="@file.Size" /></td>
<td><input asp-for="@file.UploadDateTime" /></td>
<td><input asp-for="@file.User" /></td>
<td><input asp-for="@file.Description" /></td>
<td>
<button type="submit" class="download" onclick="downloadFile(@file.Id, $(this).attr('name'))" name="@Url.Action("Download", "File", new { id = @file.Id })" title="Скачать файл" />
@if (User.IsInRole("admin"))
{
<button type="submit" class="delete" onclick="deleteFile(@file.Id)" title="Удалить файл" />
}
</td>
</tr>
}
</table>
}
else
{
<br/><h3>Не найдено файлов по запросу.</h3>
<br /><h4>Файлы не найдены.</h4>
}
</div>
<script>
function downloadFile(id, url) {
console.log("url: " + url);
console.log("id: " + id);
$.get('@Url.Action("IsExist", "File")', { id: id })
.done(function (message) {
location.href = url;
})
.fail(function (xhr, status, error) {
searchFiles();
alert(xhr.responseText);
})
}
function deleteFile(id) {
$.get('@Url.Action("Delete", "File")', { id: id })
.done(function (message) {
searchFiles();
alert(message);
})
.fail(function (xhr, status, error) {
searchFiles();
alert(xhr.responseText);
})
}
</script>
<style>
img {
height: 30px;
width: 30px;
height: 30px;
width: 30px;
}
.download {
height: 30px;
width: 30px;
background-image: url(~/images/Download.png);
background-image: url(/images/Download.png);
background-size: cover;
}
.delete {
height: 30px;
width: 30px;
background-image: url(/images/Delete.png);
background-size: cover;
}
</style>
\ No newline at end of file
@using FileDesk.Web
@using FileDesk.Web.Models
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
\ No newline at end of file
......@@ -13,9 +13,10 @@ a {
}
.btn-primary {
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
color: #fff;
background-color: #1b6ec2;
border-color: #1861ac;
margin-right: 50px;
}
.nav-pills .nav-link.active, .nav-pills .show > .nav-link {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment