using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using Core;
using LiMan.APi.Data;
using LiMan.DB.DBModels;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace LiMan.APi.Controllers
{
///
/// Controller caricamento file
///
[ApiController]
[Route("api/filesave")]
public class FilesaveController : ControllerBase
{
private readonly IWebHostEnvironment env;
private readonly ILogger logger;
private static IConfiguration _configuration;
///
/// Dataservice x accesso DB
///
protected ApiDataService dataService { get; set; }
///
/// Init generico
///
///
///
///
///
public FilesaveController(IConfiguration configuration, ApiDataService DataService, IWebHostEnvironment env, ILogger logger)
{
dataService = DataService;
_configuration = configuration;
this.env = env;
this.logger = logger;
logger.LogInformation("Avviata classe FilesaveController");
}
///
/// Caricamento file effettivo via POST
///
/// TicketId x riferimento
/// Elenco files da caricare
///
[HttpPost("single")]
public async Task> PostSingleFile([FromForm] int ticketId, [FromForm] IFormFile file)
{
// max 200 mb
long maxFileSize = 1024 * 1024 * 200;
string ticketDir = $"T{ticketId:000000000}";
var resourcePath = new Uri($"{Request.Scheme}://{Request.Host}/api/filesave/list/{ticketId}");
List uploadResults = new();
string fileDir = env.ContentRootPath;
string relDir = env.EnvironmentName;
var uploadResult = new UploadResult();
string trustedFileNameForFileStorage;
var untrustedFileName = file.FileName;
uploadResult.FileName = untrustedFileName;
var trustedFileNameForDisplay = WebUtility.HtmlEncode(untrustedFileName);
if (file.Length == 0)
{
logger.LogInformation("{FileName} length is 0 (Err: 1)", trustedFileNameForDisplay);
uploadResult.ErrorCode = 1;
}
else if (file.Length > maxFileSize)
{
logger.LogInformation("{FileName} of {Length} bytes is larger than the limit of {Limit} bytes (Err: 2)", trustedFileNameForDisplay, file.Length, maxFileSize);
uploadResult.ErrorCode = 2;
}
else
{
try
{
DateTime oggi = DateTime.Today;
trustedFileNameForFileStorage = Path.GetRandomFileName();
#if false
relDir = Path.Combine(env.EnvironmentName, "unsafe_uploads", ticketDir);
fileDir = Path.Combine(env.ContentRootPath, relDir);
//string fileDir = Path.Combine(env.ContentRootPath, env.EnvironmentName, "unsafe_uploads", $"{oggi:yyyy}", $"{oggi:MM}", $"{oggi:dd}");
#endif
relDir = _configuration["FileShare"];
fileDir = Path.Combine(relDir, ticketDir);
if (!Directory.Exists(fileDir))
{
Directory.CreateDirectory(fileDir);
}
var path = Path.Combine(fileDir, trustedFileNameForFileStorage);
await using FileStream fs = new(path, FileMode.Create);
await file.CopyToAsync(fs);
logger.LogInformation("{FileName} saved at {Path}", trustedFileNameForDisplay, path);
uploadResult.Uploaded = true;
uploadResult.StoredFileName = trustedFileNameForFileStorage;
}
catch (IOException ex)
{
logger.LogError("{FileName} error on upload (Err: 3): {Message}", trustedFileNameForDisplay, ex.Message);
uploadResult.ErrorCode = 3;
}
}
uploadResults.Add(uploadResult);
// salvo su DB
var fatto = dataService.FileAdd(ticketId, relDir, uploadResults);
return new CreatedResult(resourcePath, uploadResult);
}
///
/// Caricamento file effettivo via POST
///
/// TicketId x riferimento
/// Elenco files da caricare
///
[HttpPost()]
public async Task>> PostFiles([FromForm] int ticketId, [FromForm] IEnumerable files)
{
// max 5 files
var maxAllowedFiles = 10;
// max 50 mb
long maxFileSize = 1024 * 1024 * 50;
var filesProcessed = 0;
string ticketDir = $"T{ticketId:000000000}";
var resourcePath = new Uri($"{Request.Scheme}://{Request.Host}/api/filesave/list/{ticketId}");
List uploadResults = new();
string fileDir = env.ContentRootPath;
string relDir = env.EnvironmentName;
foreach (var file in files)
{
var uploadResult = new UploadResult();
string trustedFileNameForFileStorage;
var untrustedFileName = file.FileName;
uploadResult.FileName = untrustedFileName;
var trustedFileNameForDisplay = WebUtility.HtmlEncode(untrustedFileName);
if (filesProcessed < maxAllowedFiles)
{
if (file.Length == 0)
{
logger.LogInformation("{FileName} length is 0 (Err: 1)", trustedFileNameForDisplay);
uploadResult.ErrorCode = 1;
}
else if (file.Length > maxFileSize)
{
logger.LogInformation("{FileName} of {Length} bytes is larger than the limit of {Limit} bytes (Err: 2)", trustedFileNameForDisplay, file.Length, maxFileSize);
uploadResult.ErrorCode = 2;
}
else
{
try
{
DateTime oggi = DateTime.Today;
trustedFileNameForFileStorage = Path.GetRandomFileName();
relDir = Path.Combine(env.EnvironmentName, "unsafe_uploads", ticketDir);
fileDir = Path.Combine(env.ContentRootPath, relDir);
//string fileDir = Path.Combine(env.ContentRootPath, env.EnvironmentName, "unsafe_uploads", $"{oggi:yyyy}", $"{oggi:MM}", $"{oggi:dd}");
if (!Directory.Exists(fileDir))
{
Directory.CreateDirectory(fileDir);
}
var path = Path.Combine(fileDir, trustedFileNameForFileStorage);
await using FileStream fs = new(path, FileMode.Create);
await file.CopyToAsync(fs);
logger.LogInformation("{FileName} saved at {Path}", trustedFileNameForDisplay, path);
uploadResult.Uploaded = true;
uploadResult.StoredFileName = trustedFileNameForFileStorage;
}
catch (IOException ex)
{
logger.LogError("{FileName} error on upload (Err: 3): {Message}", trustedFileNameForDisplay, ex.Message);
uploadResult.ErrorCode = 3;
}
}
filesProcessed++;
}
else
{
logger.LogInformation("{FileName} not uploaded because the request exceeded the allowed {Count} of files (Err: 4)", trustedFileNameForDisplay, maxAllowedFiles);
uploadResult.ErrorCode = 4;
}
uploadResults.Add(uploadResult);
}
// salvo su DB
var fatto = dataService.FileAdd(ticketId, relDir, uploadResults);
return new CreatedResult(resourcePath, uploadResults);
}
///
/// Richiesta di registrazione ticket supporto
///
/// Obj Richiesta
// POST api/files/list/1
[HttpPost("list/{id}")]
public async Task> list(int id, [FromBody] SupportRequest CurrRequest)
{
List result = new List();
// controllo valori
if (CurrRequest.IsValid)
{
// cerco i files dato ticket
result = await dataService.FileGetFilt(id);
await dataService.recordCall(CurrRequest.CodInst, CurrRequest.CodApp, $"POST:api/files/list:{id}");
}
return result;
}
}
}