From afa133a8f24e03b2f5fdb32a856e8398b6ce1149 Mon Sep 17 00:00:00 2001 From: michele Date: Wed, 24 Sep 2025 12:50:49 +0200 Subject: [PATCH 1/3] Modifiche pagina download --- Controllers/HomeController.cs | 2 +- Views/Home/VT_Read.cshtml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Controllers/HomeController.cs b/Controllers/HomeController.cs index f7167f9..e6946e9 100644 --- a/Controllers/HomeController.cs +++ b/Controllers/HomeController.cs @@ -68,7 +68,7 @@ namespace VirtualTask.Controllers string app = ""; byte[] fileBytes = System.IO.File.ReadAllBytes(file); var response = new FileContentResult(fileBytes, "application/octet-stream"); - response.FileDownloadName = "appTest.apk"; + response.FileDownloadName = "app_Virtual_Task_1_34.apk"; return response; } diff --git a/Views/Home/VT_Read.cshtml b/Views/Home/VT_Read.cshtml index 0ba844f..f440e58 100644 --- a/Views/Home/VT_Read.cshtml +++ b/Views/Home/VT_Read.cshtml @@ -4,6 +4,6 @@ }

@ViewData["Title"]

-

Download Android App (ver. 1.25)

+

Download Android App (ver. 1.34)

From fb49116bba5a207ab20b49474ebc8a22dae932c6 Mon Sep 17 00:00:00 2001 From: michele Date: Mon, 29 Sep 2025 09:46:23 +0200 Subject: [PATCH 2/3] Aggiunta classe lightbox in immagini portale (VT_page2 e VT_page3) Impaginazione pagina foto --- Views/Portale/VT_Page2.cshtml | 103 ++++++++++++++++++++-- Views/Portale/VT_Page3.cshtml | 151 ++++++++++++++++++++++---------- Views/Rapp_New/ShowImage.cshtml | 32 ++++--- 3 files changed, 224 insertions(+), 62 deletions(-) diff --git a/Views/Portale/VT_Page2.cshtml b/Views/Portale/VT_Page2.cshtml index 78bb392..2578b65 100644 --- a/Views/Portale/VT_Page2.cshtml +++ b/Views/Portale/VT_Page2.cshtml @@ -4,6 +4,68 @@ ViewData["Title"] = "Virtual Task Pro"; } + + +
@@ -30,8 +92,8 @@
- Virtual Task App - Virtual Task App + Virtual Task App + Virtual Task App
@@ -60,7 +122,7 @@
- Virtual Task App + Virtual Task App
    @@ -124,8 +186,8 @@
    - Virtual Task App - Virtual Task App + Virtual Task App + Virtual Task App
    @@ -164,6 +226,37 @@ + + + +@section Scripts { + +} + @* +} diff --git a/Views/Rapp_New/ShowImage.cshtml b/Views/Rapp_New/ShowImage.cshtml index 6e462c8..6b0fa82 100644 --- a/Views/Rapp_New/ShowImage.cshtml +++ b/Views/Rapp_New/ShowImage.cshtml @@ -5,15 +5,25 @@

    @ViewData["Title"]

    -@if (!string.IsNullOrEmpty(fileName)) -{ -
    - Immagine: @fileName + +
    +
    +
    +
    + @if (!string.IsNullOrEmpty(fileName)) + { +
    + Immagine: @fileName +
    + } + else + { +

    Nessuna immagine specificata.

    + } +
    +
    -} -else -{ -

    Nessuna immagine specificata.

    -} +
    + From 0f7665b7617e6e83790c5f6445c2609f097131fc Mon Sep 17 00:00:00 2001 From: michele Date: Fri, 3 Oct 2025 12:40:48 +0200 Subject: [PATCH 3/3] modifica dati azienda, create e edit per upload logo --- Controllers/DatiAziendaController.cs | 279 ++++++++++++--------------- Views/DatiAzienda/Delete.cshtml | 4 +- appsettings.json | 11 +- 3 files changed, 135 insertions(+), 159 deletions(-) diff --git a/Controllers/DatiAziendaController.cs b/Controllers/DatiAziendaController.cs index 95277a6..0657f95 100644 --- a/Controllers/DatiAziendaController.cs +++ b/Controllers/DatiAziendaController.cs @@ -91,99 +91,82 @@ namespace VirtualTask.Controllers } [HttpPost] - public IActionResult Create(DatiAzienda model) + public async Task Create(DatiAzienda model) { - DatiAziendaTable dat=new DatiAziendaTable(); - SessionHelper helper = new SessionHelper(this); - admin = helper.GetStringValue("admin"); - token = helper.GetStringValue("tok"); - tenant = helper.GetStringValue("tenant"); - tenant2 = helper.GetStringValue("tenant2"); + string token = helper.GetStringValue("tok"); + string tenant2 = helper.GetStringValue("tenant2"); // tenant = azienda + + string apiUrl = helper.GetStringValue("apiUrl"); + string admin = helper.GetStringValue("admin"); ViewBag.Admin = admin; - if (model.logo != null) + ViewBag.AllTecnici = getTecnici(); + + if (!ModelState.IsValid) + return View(model); + + string logoUrl = null; + + // 1️⃣ Upload del logo tramite API UploadLogo + // 1️⃣ Upload del logo tramite API UploadLogo + if (model.logo != null && model.logo.Length > 0) { - string pic = System.IO.Path.GetFileName(model.logo.FileName); - //2025-05-05: gestione directory iommagine nel caso che l'azienda sia più corta di 5 caratteri - string dir = tenant2; - if (!string.IsNullOrEmpty(tenant2) && tenant2.Trim().Length < 5) - { - dir = tenant2.Trim(); - } - string path = string.Format("{0}{1}\\{2}",_pathLoghi, dir, pic); - //string projectRootPath = _hostingEnvironment.ContentRootPath; + // ✅ Token nella query string + string uploadUrl = $"{apiUrl}datiazienda/upload_logo?token={token}"; - //// file is uploaded - using (Stream fileStream = new FileStream(path, FileMode.Create)) + using (var httpClient = new HttpClient()) + using (var form = new MultipartFormDataContent()) { - model.logo.CopyToAsync(fileStream); + // ⚡ Solo il file nel multipart + var fileContent = new StreamContent(model.logo.OpenReadStream()); + fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue( + string.IsNullOrWhiteSpace(model.logo.ContentType) ? "application/octet-stream" : model.logo.ContentType + ); + form.Add(fileContent, "file", model.logo.FileName); + + HttpResponseMessage response = await httpClient.PostAsync(uploadUrl, form); + + if (!response.IsSuccessStatusCode) + { + string err = await response.Content.ReadAsStringAsync(); + ModelState.AddModelError("", "Errore upload logo: " + err); + return View(model); + } + + dynamic result = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); + logoUrl = result.url; } - //// save the image path path to the database or you can send image - //// directly to database - //// in-case if you want to store byte[] ie. for DB - using (MemoryStream ms = new MemoryStream()) - { - model.logo.CopyTo(ms); - byte[] array = ms.GetBuffer(); - dat.logo = array; - } - dat.azienda = tenant2; - dat.testo_buono = model.testo_buono; - dat.url_logo = string.Format("{0}{1}/{2}", _urlLoghi, dir, pic); - dat.ragsoc = model.ragsoc; - dat.tecnico = model.tecnico; } - - - apiUrl = helper.GetStringValue("apiUrl"); - admin = helper.GetStringValue("admin"); - ViewBag.Admin = admin; - urlBase = apiUrl + "datiazienda/add"; - urlBase = urlBase + "?token=" + token; - Uri baseAddress = new Uri(urlBase); - client = new HttpClient(); - client.BaseAddress = baseAddress; - - string data = JsonConvert.SerializeObject(dat); - StringContent content = new StringContent(data, Encoding.UTF8, "application/json"); - HttpResponseMessage response = client.PostAsync(baseAddress, content).Result; - - if (response.IsSuccessStatusCode) + // 2️⃣ Creazione oggetto da inviare all'API datiazienda/add + var dat = new DatiAziendaTable { - //prima di andare alla pagina devo chiamare il metodo per - //salvare il file in locale in modo che sia visibile sul web dall'app - //C:\ZAPIPOLO\loghi - //https://api.poloinformatico.it:9000/api/Polo/datiazienda/saveFile?azienda=AZI02&tecnico=aaaaa%20%20%20%20%20%20%20%20%20%20&pathSrv=C%3A%5CZAPIPOLO%5Cloghi' - apiUrl = helper.GetStringValue("apiUrl"); - urlBase = apiUrl + "datiazienda/savefile"; - urlBase = urlBase + "?azienda=" + model.azienda; - urlBase = urlBase + "&tecnico=" + model.tecnico; - //urlBase = urlBase + "&pathSrv=" + "C:\\ZAPIPOLO\\loghi"; - urlBase = urlBase + "&pathSrv=" + _pathLoghi; - - baseAddress = new Uri(urlBase); - client = new HttpClient(); - client.BaseAddress = baseAddress; - HttpResponseMessage response2 = client.GetAsync(baseAddress).Result; - if (response2.IsSuccessStatusCode) + azienda = tenant2, + tecnico = model.tecnico, + ragsoc = model.ragsoc, + testo_buono = model.testo_buono, + url_logo = logoUrl, + logo = model.logo != null ? await ConvertToByteArrayAsync(model.logo) : null + }; + + // 3️⃣ Invio dati all'API datiazienda/add + string apiAddUrl = apiUrl + "datiazienda/add?token=" + token; + using (var httpClient = new HttpClient()) + { + string data = JsonConvert.SerializeObject(dat); + StringContent content = new StringContent(data, Encoding.UTF8, "application/json"); + HttpResponseMessage saveResponse = await httpClient.PostAsync(apiAddUrl, content); + + if (!saveResponse.IsSuccessStatusCode) { - return RedirectToAction("Index"); - } - else - { - errMes = response.Content.ReadAsStringAsync().Result; - helper.SetStringValue("errMsg", errMes); - return RedirectToAction("Error"); + string err = await saveResponse.Content.ReadAsStringAsync(); + ModelState.AddModelError("", "Errore salvataggio dati: " + err); + return View(model); } } - else - { - errMes = response.Content.ReadAsStringAsync().Result; - helper.SetStringValue("errMsg", errMes); - return RedirectToAction("Error"); - } + + return RedirectToAction("Index"); } #endregion CREATE @@ -228,103 +211,72 @@ namespace VirtualTask.Controllers } [HttpPost] - public IActionResult Edit(DatiAziendaTable model) + public async Task Edit(DatiAziendaTable model) { SessionHelper helper = new SessionHelper(this); - token = helper.GetStringValue("tok"); - tenant = helper.GetStringValue("tenant"); - tenant2 = helper.GetStringValue("tenant2"); + string token = helper.GetStringValue("tok"); + string tenant2 = helper.GetStringValue("tenant2"); if (string.IsNullOrEmpty(token)) - { return RedirectToAction("Login2", "Login"); - } - //model.azienda = tenant; - if(model.logo2!=null) + + string apiUrl = helper.GetStringValue("apiUrl"); + + // 1️⃣ Upload del logo tramite API UploadLogo + if (model.logo2 != null && model.logo2.Length > 0) { - string pic = System.IO.Path.GetFileName(model.logo2.FileName); + string uploadUrl = $"{apiUrl}datiazienda/upload_logo?token={token}"; - //2025-05-05: gestione directory iommagine nel caso che l'azienda sia più corta di 5 caratteri - string dir = tenant2; - if (!string.IsNullOrEmpty(tenant2) && tenant2.Trim().Length < 5) + using (var httpClient = new HttpClient()) + using (var form = new MultipartFormDataContent()) { - dir = tenant2.Trim(); - } - string path = string.Format("{0}{1}\\{2}", _pathLoghi, dir, pic); - //string projectRootPath = _hostingEnvironment.ContentRootPath; - - //// file is uploaded - using (Stream fileStream = new FileStream(path, FileMode.Create)) - { - model.logo2.CopyToAsync(fileStream); + var fileContent = new StreamContent(model.logo2.OpenReadStream()); + fileContent.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue( + string.IsNullOrWhiteSpace(model.logo2.ContentType) ? "application/octet-stream" : model.logo2.ContentType + ); + form.Add(fileContent, "file", model.logo2.FileName); + + HttpResponseMessage response = await httpClient.PostAsync(uploadUrl, form); + if (!response.IsSuccessStatusCode) + { + string err = await response.Content.ReadAsStringAsync(); + ModelState.AddModelError("", "Errore upload logo: " + err); + return View(model); + } + + dynamic result = JsonConvert.DeserializeObject(await response.Content.ReadAsStringAsync()); + model.url_logo = result.url; } - //// save the image path path to the database or you can send image - //// directly to database - //// in-case if you want to store byte[] ie. for DB + // Salvo i byte del file nel modello se serve per il DB using (MemoryStream ms = new MemoryStream()) { - model.logo2.CopyTo(ms); - byte[] array = ms.GetBuffer(); - model.logo = array; + await model.logo2.CopyToAsync(ms); + model.logo = ms.ToArray(); } model.logo2 = null; - model.url_logo = string.Format("{0}{1}/{2}", _urlLoghi, dir, pic); } - - apiUrl = helper.GetStringValue("apiUrl"); - urlBase = apiUrl + "datiazienda/mod"; - urlBase = urlBase + "?token=" + token; - Uri baseAddress = new Uri(urlBase); - client = new HttpClient(); - client.BaseAddress = baseAddress; - - string data = JsonConvert.SerializeObject(model); - StringContent content = new StringContent(data, Encoding.UTF8, "application/json"); - HttpResponseMessage response = client.PostAsync(baseAddress, content).Result; - - if (response.IsSuccessStatusCode) + // 2️⃣ Invio dati all'API datiazienda/mod + string modUrl = $"{apiUrl}datiazienda/mod?token={token}"; + using (var client = new HttpClient()) { - //prima di andare alla pagina devo chiamare il metodo per - //salvare il file in locale in modo che sia visibile sul web dall'app - //C:\ZAPIPOLO\loghi - //https://api.poloinformatico.it:9000/api/Polo/datiazienda/saveFile?azienda=AZI02&tecnico=aaaaa%20%20%20%20%20%20%20%20%20%20&pathSrv=C%3A%5CZAPIPOLO%5Cloghi' - apiUrl = helper.GetStringValue("apiUrl"); - urlBase = apiUrl + "datiazienda/savefile"; - if(!string.IsNullOrEmpty(model.azienda) && model.azienda.Length<5) - { - model.azienda= model.azienda.Trim(); - } - urlBase = urlBase + "?azienda=" + model.azienda; - urlBase = urlBase + "&tecnico=" + model.tecnico.Trim(); - urlBase = urlBase + "&pathSrv=" + _pathLoghi; - baseAddress = new Uri(urlBase); - client = new HttpClient(); - client.BaseAddress = baseAddress; + string data = JsonConvert.SerializeObject(model); + StringContent content = new StringContent(data, Encoding.UTF8, "application/json"); + HttpResponseMessage response = await client.PostAsync(modUrl, content); - data = JsonConvert.SerializeObject(model); - content = new StringContent(data, Encoding.UTF8, "application/json"); - HttpResponseMessage response2 = client.PostAsync(baseAddress, content).Result; - if (response2.IsSuccessStatusCode) + if (!response.IsSuccessStatusCode) { - return RedirectToAction("Index"); - } - else - { - errMes = response2.Content.ReadAsStringAsync().Result; + string errMes = await response.Content.ReadAsStringAsync(); helper.SetStringValue("errMsg", errMes); return RedirectToAction("Error"); } } - else - { - errMes = response.Content.ReadAsStringAsync().Result; - helper.SetStringValue("errMsg", errMes); - return RedirectToAction("Error"); - } + + return RedirectToAction("Index"); } + #endregion #region DETAIL @@ -435,7 +387,7 @@ namespace VirtualTask.Controllers } #endregion DELETE - + #region ALTRI METODI [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] public IActionResult Error() { @@ -443,6 +395,7 @@ namespace VirtualTask.Controllers string e = helper.GetStringValue("errMsg"); return View(new ErrorViewModel { RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier, ErrMsg = e }); } + private List getTecnici() { SessionHelper helper = new SessionHelper(this); @@ -480,5 +433,27 @@ namespace VirtualTask.Controllers } return selectItems; } + + + // Metodo helper per convertire IFormFile in byte[] + private async Task ConvertToByteArrayAsync(IFormFile file) + { + using (var ms = new MemoryStream()) + { + await file.CopyToAsync(ms); + return ms.ToArray(); + } + } + #endregion ALTRI METODI + + // Classe per deserializzare la risposta JSON dell'API + private class UploadResponse + { + public string? message { get; set; } + public string? url { get; set; } + public string? fileName { get; set; } + } } + + } diff --git a/Views/DatiAzienda/Delete.cshtml b/Views/DatiAzienda/Delete.cshtml index 99be8fd..10c604d 100644 --- a/Views/DatiAzienda/Delete.cshtml +++ b/Views/DatiAzienda/Delete.cshtml @@ -60,9 +60,7 @@ model.azienda) name="azienda" /> model.tecnico) name="tecnico" /> - + Torna alla lista
    diff --git a/appsettings.json b/appsettings.json index 645df6c..d355d84 100644 --- a/appsettings.json +++ b/appsettings.json @@ -7,10 +7,12 @@ }, "ApplicationInsights": { - ////PRODUZIONE + //PRODUZIONE "rootUrlApi": "https://api-vt.poloinformatico.it/api/Polo/", "rootUrlApi2": "https://api-vt.poloinformatico.it/VIRTU/", - "rootWebLoghi": "C:\\ZAPIPOLO\\api_polo\\wwwroot\\VIRTU\\", + //"rootWebLoghi": "C:\\ZAPIPOLO\\api_polo\\wwwroot\\VIRTU\\", + //"rootWebLoghi": "/zucchetti/api/api-vt.poloinformatico.it/app/wwwroot/VIRTU/", + "rootWebLoghi": "./wwwroot/VIRTU", "rootUrl": "https://virtualtask.it/", "rootPath": "/mnt/storagebox", @@ -20,10 +22,11 @@ //"rootWebLoghi": "C:\\Users\\audif\\source\\repos\\VirtualTask\\wwwroot\\VIRTU\\", //"rootUrl": "https://localhost:7140/", - //MICHELE: PUNTAMENTO A MIO PC PER FARE I TEST + ////MICHELE: PUNTAMENTO A MIO PC PER FARE I TEST //"rootUrlApi": "https://localhost:7068/api/Polo/", //"rootUrlApi2": "https://localhost:7068//VIRTU/", - //"rootWebLoghi": "C:\\Users\\audif\\source\\repos\\VirtualTask\\wwwroot\\VIRTU\\", + ////"rootWebLoghi": "C:\\Users\\audif\\source\\repos\\VirtualTask\\wwwroot\\VIRTU\\", + //"rootWebLoghi": "/zucchetti/api/api-vt.poloinformatico.it/app/wwwroot/VIRTU/", //"rootUrl": "https://localhost:7068/", "mittenteMail": "info@virtualtask.it",