refactor: simplifier les actions du contrôleur en supprimant les contrôles ModelState redondants et en améliorant la récupération des données
This commit is contained in:
@@ -37,11 +37,9 @@ public class ArtisteController : Controller
|
|||||||
/// <returns>Redirection.</returns>
|
/// <returns>Redirection.</returns>
|
||||||
public IActionResult Index()
|
public IActionResult Index()
|
||||||
{
|
{
|
||||||
IEnumerable<Artiste> artistes = this.artisteRepository.FindAll();
|
IEnumerable<Artiste> artistes = this.artisteRepository.FindAll().OrderBy(t => t.Nom);
|
||||||
|
|
||||||
var artistes_ordre = artistes.OrderBy(t => t.Nom).ToList();
|
return this.View(artistes);
|
||||||
|
|
||||||
return this.View(artistes_ordre);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -61,14 +59,6 @@ public class ArtisteController : Controller
|
|||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult Create(ArtisteCreateViewModel model)
|
public IActionResult Create(ArtisteCreateViewModel model)
|
||||||
{
|
{
|
||||||
// vérifier si les données sont corrects.
|
|
||||||
if (!this.ModelState.IsValid)
|
|
||||||
{
|
|
||||||
// Passer model en paramètre afin que
|
|
||||||
// l'utilisateur conserve sa saissie.
|
|
||||||
return this.View(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Créer un objet Artiste avecc les paramètres.
|
// Créer un objet Artiste avecc les paramètres.
|
||||||
var artiste = new Artiste
|
var artiste = new Artiste
|
||||||
{
|
{
|
||||||
@@ -115,11 +105,6 @@ public class ArtisteController : Controller
|
|||||||
Biographie = model.Biographie,
|
Biographie = model.Biographie,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!this.ModelState.IsValid)
|
|
||||||
{
|
|
||||||
return this.View(artiste);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.artisteRepository.Update(artiste);
|
this.artisteRepository.Update(artiste);
|
||||||
|
|
||||||
return this.RedirectToAction("Index");
|
return this.RedirectToAction("Index");
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ namespace Webzine.WebApplication.Areas.Administration.Controllers
|
|||||||
using Webzine.Repository.Contracts;
|
using Webzine.Repository.Contracts;
|
||||||
using Webzine.WebApplication.Areas.Administration.ViewModels.Commentaire;
|
using Webzine.WebApplication.Areas.Administration.ViewModels.Commentaire;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
[Area("Administration")]
|
[Area("Administration")]
|
||||||
public class CommentaireController : Controller
|
public class CommentaireController : Controller
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public class DashboardController : Controller
|
|||||||
/// <returns>La vue Index du tableau de bord.</returns>
|
/// <returns>La vue Index du tableau de bord.</returns>
|
||||||
public IActionResult Index()
|
public IActionResult Index()
|
||||||
{
|
{
|
||||||
DashboardDTO data = dashboardService.GetDashboardData();
|
DashboardDTO data = this.dashboardService.GetDashboardData();
|
||||||
|
|
||||||
return this.View(data);
|
return this.View(data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,11 +63,6 @@ public class StyleController : Controller
|
|||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult Create(StyleCreateViewModel model)
|
public IActionResult Create(StyleCreateViewModel model)
|
||||||
{
|
{
|
||||||
if (!this.ModelState.IsValid)
|
|
||||||
{
|
|
||||||
return this.View(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
var style = new Style
|
var style = new Style
|
||||||
{
|
{
|
||||||
Libelle = model.Libelle,
|
Libelle = model.Libelle,
|
||||||
@@ -124,7 +119,6 @@ public class StyleController : Controller
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="id">L'identifiant du style a editer.</param>
|
/// <param name="id">L'identifiant du style a editer.</param>
|
||||||
/// <returns>La vue d'edition ou une redirection vers l'index si le style n'existe pas.</returns>
|
/// <returns>La vue d'edition ou une redirection vers l'index si le style n'existe pas.</returns>
|
||||||
[HttpGet]
|
|
||||||
public IActionResult Edit(int id)
|
public IActionResult Edit(int id)
|
||||||
{
|
{
|
||||||
var style = this.styleRepository.Find(id);
|
var style = this.styleRepository.Find(id);
|
||||||
@@ -151,11 +145,6 @@ public class StyleController : Controller
|
|||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult Edit(StyleEditViewModel model)
|
public IActionResult Edit(StyleEditViewModel model)
|
||||||
{
|
{
|
||||||
if (!this.ModelState.IsValid)
|
|
||||||
{
|
|
||||||
return this.View(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
var style = this.styleRepository.Find(model.IdStyle);
|
var style = this.styleRepository.Find(model.IdStyle);
|
||||||
if (style == null)
|
if (style == null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -94,16 +94,11 @@ public class TitreController : Controller
|
|||||||
/// <returns>Redirection vers Index en cas de succès, réaffichage du formulaire sinon.</returns>
|
/// <returns>Redirection vers Index en cas de succès, réaffichage du formulaire sinon.</returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult Create(TitreAdminDTO model)
|
public IActionResult Create(TitreAdminDTO model)
|
||||||
{
|
|
||||||
if (this.ModelState.IsValid)
|
|
||||||
{
|
{
|
||||||
this.titreAdminService.CreerTitre(model);
|
this.titreAdminService.CreerTitre(model);
|
||||||
return this.RedirectToAction("Index");
|
return this.RedirectToAction("Index");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.View(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Affiche le formulaire de modification d'un titre existant dans la vue Edit, en préremplissant les champs avec les données du titre sélectionné. Les listes déroulantes pour les artistes et les styles sont également remplies pour permettre à l'utilisateur de modifier ces associations.
|
/// Affiche le formulaire de modification d'un titre existant dans la vue Edit, en préremplissant les champs avec les données du titre sélectionné. Les listes déroulantes pour les artistes et les styles sont également remplies pour permettre à l'utilisateur de modifier ces associations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -151,16 +146,11 @@ public class TitreController : Controller
|
|||||||
/// <returns>Redirection vers Index en cas de succès, réaffichage du formulaire sinon.</returns>
|
/// <returns>Redirection vers Index en cas de succès, réaffichage du formulaire sinon.</returns>
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult Edit(TitreAdminDTO model)
|
public IActionResult Edit(TitreAdminDTO model)
|
||||||
{
|
|
||||||
if (this.ModelState.IsValid)
|
|
||||||
{
|
{
|
||||||
this.titreAdminService.ModifierTitre(model);
|
this.titreAdminService.ModifierTitre(model);
|
||||||
return this.RedirectToAction("Index");
|
return this.RedirectToAction("Index");
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.View(model);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Affiche la vue de confirmation de suppression d'un titre, en récupérant les détails du titre à supprimer à partir de l'identifiant fourni. Le ViewModel contient les informations essentielles du titre, telles que le libellé et le nom de l'artiste, pour permettre à l'utilisateur de confirmer la suppression.
|
/// Affiche la vue de confirmation de suppression d'un titre, en récupérant les détails du titre à supprimer à partir de l'identifiant fourni. Le ViewModel contient les informations essentielles du titre, telles que le libellé et le nom de l'artiste, pour permettre à l'utilisateur de confirmer la suppression.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Service de journalisation injecté pour enregistrer les événements et les erreurs.</param>
|
/// <param name="logger">Service de journalisation injecté pour enregistrer les événements et les erreurs.</param>
|
||||||
/// <param name="configuration">Service d'injection de configuration pour accéder aux paramètres de l'application.</param>
|
/// <param name="configuration">Service d'injection de configuration pour accéder aux paramètres de l'application.</param>
|
||||||
|
/// <param name="titreRepository"></param>
|
||||||
public AccueilController(
|
public AccueilController(
|
||||||
ILogger<AccueilController> logger,
|
ILogger<AccueilController> logger,
|
||||||
IConfiguration configuration,
|
IConfiguration configuration,
|
||||||
|
|||||||
@@ -2,12 +2,14 @@ namespace Webzine.WebApplication.Controllers;
|
|||||||
|
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Controller de version de l'API.
|
||||||
|
/// </summary>
|
||||||
public class ApiController : ControllerBase
|
public class ApiController : ControllerBase
|
||||||
{
|
{
|
||||||
private readonly ILogger<ApiController> logger;
|
private readonly ILogger<ApiController> logger;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="ApiController"/> class.
|
|
||||||
/// Initialise une nouvelle instance de la classe <see cref="ApiController"/>.
|
/// Initialise une nouvelle instance de la classe <see cref="ApiController"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Service de journalisation injecté pour enregistrer les événements et les erreurs.</param>
|
/// <param name="logger">Service de journalisation injecté pour enregistrer les événements et les erreurs.</param>
|
||||||
@@ -21,7 +23,6 @@ public class ApiController : ControllerBase
|
|||||||
/// Endpoint de test pour vérifier que l'API fonctionne correctement. Retourne un objet JSON contenant le nom et la version de l'application.
|
/// Endpoint de test pour vérifier que l'API fonctionne correctement. Retourne un objet JSON contenant le nom et la version de l'application.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>Un objet JSON avec les propriétés "nom" et "version".</returns>
|
/// <returns>Un objet JSON avec les propriétés "nom" et "version".</returns>
|
||||||
[HttpGet]
|
|
||||||
public IActionResult Version()
|
public IActionResult Version()
|
||||||
{
|
{
|
||||||
this.logger.LogInformation("Get Version was called");
|
this.logger.LogInformation("Get Version was called");
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
using Webzine.Repository.Contracts;
|
using Webzine.Repository.Contracts;
|
||||||
using Webzine.WebApplication.ViewModels.Artiste;
|
using Webzine.WebApplication.ViewModels.Artiste;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public class ArtisteController : Controller
|
public class ArtisteController : Controller
|
||||||
{
|
{
|
||||||
// Injection du logger via le constructeur
|
// Injection du logger via le constructeur
|
||||||
@@ -16,6 +19,7 @@
|
|||||||
/// Initialise une nouvelle instance du <see cref="ArtisteController"/>. avec un service de journalisation injecté.
|
/// Initialise une nouvelle instance du <see cref="ArtisteController"/>. avec un service de journalisation injecté.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="logger">Service de journalisation injecté pour enregistrer les événements et les erreurs.</param>
|
/// <param name="logger">Service de journalisation injecté pour enregistrer les événements et les erreurs.</param>
|
||||||
|
/// <param name="artisteRepository"></param>
|
||||||
public ArtisteController(
|
public ArtisteController(
|
||||||
ILogger<ArtisteController> logger,
|
ILogger<ArtisteController> logger,
|
||||||
IArtisteRepository artisteRepository)
|
IArtisteRepository artisteRepository)
|
||||||
|
|||||||
@@ -9,12 +9,21 @@ namespace Webzine.WebApplication.Controllers
|
|||||||
using Webzine.Repository.Contracts;
|
using Webzine.Repository.Contracts;
|
||||||
using Webzine.WebApplication.ViewModels.Recherche;
|
using Webzine.WebApplication.ViewModels.Recherche;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
public class RechercheController : Controller
|
public class RechercheController : Controller
|
||||||
{
|
{
|
||||||
private readonly ILogger<RechercheController> logger;
|
private readonly ILogger<RechercheController> logger;
|
||||||
private readonly ITitreRepository titreRepository;
|
private readonly ITitreRepository titreRepository;
|
||||||
private readonly IArtisteRepository artisteRepository;
|
private readonly IArtisteRepository artisteRepository;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initialise une nouvelle instance de la classe <see cref="RechercheController"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger"></param>
|
||||||
|
/// <param name="titreRepository"></param>
|
||||||
|
/// <param name="artisteRepository"></param>
|
||||||
public RechercheController(
|
public RechercheController(
|
||||||
ILogger<RechercheController> logger,
|
ILogger<RechercheController> logger,
|
||||||
ITitreRepository titreRepository,
|
ITitreRepository titreRepository,
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ namespace Webzine.WebApplication.Controllers
|
|||||||
this.titreRepository.IncrementNbLikes(titre);
|
this.titreRepository.IncrementNbLikes(titre);
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.RedirectToAction("Details", new { id = model.IdTitre });
|
return this.RedirectToAction("Index", new { id = model.IdTitre });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -130,12 +130,6 @@ namespace Webzine.WebApplication.Controllers
|
|||||||
[HttpPost]
|
[HttpPost]
|
||||||
public IActionResult Comment(TitreComment model)
|
public IActionResult Comment(TitreComment model)
|
||||||
{
|
{
|
||||||
if (!this.ModelState.IsValid)
|
|
||||||
{
|
|
||||||
this.logger.LogWarning("Echec de validation du modele de commentaire pour le titre ID {Id}.", model.IdTitre);
|
|
||||||
return this.RedirectToAction("Details", new { id = model.IdTitre });
|
|
||||||
}
|
|
||||||
|
|
||||||
var titre = this.titreRepository.Find(model.IdTitre);
|
var titre = this.titreRepository.Find(model.IdTitre);
|
||||||
|
|
||||||
if (titre == null)
|
if (titre == null)
|
||||||
@@ -156,7 +150,7 @@ namespace Webzine.WebApplication.Controllers
|
|||||||
|
|
||||||
this.logger.LogInformation("Commentaire ajoute avec succes au titre ID {Id}.", model.IdTitre);
|
this.logger.LogInformation("Commentaire ajoute avec succes au titre ID {Id}.", model.IdTitre);
|
||||||
|
|
||||||
return this.RedirectToAction("Details", new { id = model.IdTitre });
|
return this.RedirectToAction("Index", new { id = model.IdTitre });
|
||||||
}
|
}
|
||||||
|
|
||||||
private static TitreStyleItem MapTitreItem(Titre titre)
|
private static TitreStyleItem MapTitreItem(Titre titre)
|
||||||
|
|||||||
42
Webzine.WebApplication/Filters/GlobalExceptionFilter.cs
Normal file
42
Webzine.WebApplication/Filters/GlobalExceptionFilter.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
namespace Webzine.WebApplication.Filters;
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Filtre d'exception global qui intercepte toute exception non gérée et la journalise automatiquement.
|
||||||
|
/// </summary>
|
||||||
|
public class GlobalExceptionFilter : IExceptionFilter
|
||||||
|
{
|
||||||
|
private readonly ILogger<GlobalExceptionFilter> logger;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="GlobalExceptionFilter"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">Service de journalisation injecté.</param>
|
||||||
|
public GlobalExceptionFilter(ILogger<GlobalExceptionFilter> logger)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void OnException(ExceptionContext context)
|
||||||
|
{
|
||||||
|
this.logger.LogError(
|
||||||
|
context.Exception,
|
||||||
|
"Erreur non gérée dans {Action} : {Message}",
|
||||||
|
context.ActionDescriptor.DisplayName,
|
||||||
|
context.Exception.Message);
|
||||||
|
|
||||||
|
context.Result = new ObjectResult(new
|
||||||
|
{
|
||||||
|
erreur = "Une erreur inattendue est survenue.",
|
||||||
|
detail = context.Exception.Message,
|
||||||
|
})
|
||||||
|
{
|
||||||
|
StatusCode = StatusCodes.Status500InternalServerError,
|
||||||
|
};
|
||||||
|
|
||||||
|
context.ExceptionHandled = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
73
Webzine.WebApplication/Filters/ValidationActionFilter.cs
Normal file
73
Webzine.WebApplication/Filters/ValidationActionFilter.cs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
namespace Webzine.WebApplication.Filters;
|
||||||
|
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Filtre d'action qui valide automatiquement le ModelState avant l'exécution du contrôleur.
|
||||||
|
/// Mesure également le temps d'exécution de chaque action (niveau Trace).
|
||||||
|
/// </summary>
|
||||||
|
public class ValidationActionFilter : IActionFilter
|
||||||
|
{
|
||||||
|
private readonly ILogger<ValidationActionFilter> logger;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="ValidationActionFilter"/> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">Service de journalisation injecté.</param>
|
||||||
|
public ValidationActionFilter(ILogger<ValidationActionFilter> logger)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void OnActionExecuting(ActionExecutingContext context)
|
||||||
|
{
|
||||||
|
if (!context.ModelState.IsValid)
|
||||||
|
{
|
||||||
|
var erreurs = context.ModelState
|
||||||
|
.Where(e => e.Value?.Errors.Count > 0)
|
||||||
|
.Select(e => $"{e.Key}: {string.Join(", ", e.Value!.Errors.Select(err => err.ErrorMessage))}")
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
this.logger.LogWarning(
|
||||||
|
"Validation échouée pour {Action} : {Erreurs}",
|
||||||
|
context.ActionDescriptor.DisplayName,
|
||||||
|
string.Join(" | ", erreurs));
|
||||||
|
|
||||||
|
string actionName = context.RouteData.Values["action"]?.ToString() ?? string.Empty;
|
||||||
|
|
||||||
|
// cas spécial: titre details
|
||||||
|
if (actionName.Equals("Index", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
context.Result = new RedirectResult("/");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Récupère le modèle soumis (premier argument de l'action, s'il existe)
|
||||||
|
object? model = context.ActionArguments.Values.FirstOrDefault();
|
||||||
|
|
||||||
|
if (context.Controller is Controller controller)
|
||||||
|
{
|
||||||
|
context.Result = new ViewResult
|
||||||
|
{
|
||||||
|
ViewName = actionName,
|
||||||
|
ViewData = new Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary(
|
||||||
|
controller.ViewData)
|
||||||
|
{
|
||||||
|
Model = model,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
context.Result = new BadRequestObjectResult(context.ModelState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public void OnActionExecuted(ActionExecutedContext context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,6 +15,7 @@ using Webzine.Repository;
|
|||||||
using Webzine.Repository.Contracts;
|
using Webzine.Repository.Contracts;
|
||||||
using Webzine.WebApplication.Configuration;
|
using Webzine.WebApplication.Configuration;
|
||||||
using Webzine.WebApplication.Extensions;
|
using Webzine.WebApplication.Extensions;
|
||||||
|
using Webzine.WebApplication.Filters;
|
||||||
using Webzine.WebApplication.Interceptors;
|
using Webzine.WebApplication.Interceptors;
|
||||||
|
|
||||||
// Initiation du logger NLog pour la classe courante afin de pouvoir l'utiliser pour logger des messages d'information, d'erreur, etc avant la construction de l'application.
|
// Initiation du logger NLog pour la classe courante afin de pouvoir l'utiliser pour logger des messages d'information, d'erreur, etc avant la construction de l'application.
|
||||||
@@ -27,8 +28,11 @@ try
|
|||||||
|
|
||||||
// Ajoute les services necessaires pour permettre l'utilisation des
|
// Ajoute les services necessaires pour permettre l'utilisation des
|
||||||
// controllers avec des vues.
|
// controllers avec des vues.
|
||||||
builder.Services.AddControllersWithViews()
|
builder.Services.AddControllersWithViews(options =>
|
||||||
|
{
|
||||||
|
options.Filters.Add<ValidationActionFilter>();
|
||||||
|
options.Filters.Add<GlobalExceptionFilter>();
|
||||||
|
})
|
||||||
// Ajoute la compilation des vues lors de l'execution de l'application.
|
// Ajoute la compilation des vues lors de l'execution de l'application.
|
||||||
// Cela nous evite de recompiler l'application a chaque modification de vue.
|
// Cela nous evite de recompiler l'application a chaque modification de vue.
|
||||||
// Necessite le package Nuget Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.
|
// Necessite le package Nuget Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation.
|
||||||
@@ -87,6 +91,9 @@ try
|
|||||||
builder.Services.AddScoped<IDashboardService, DashboardService>();
|
builder.Services.AddScoped<IDashboardService, DashboardService>();
|
||||||
builder.Services.AddScoped<ITitreAdminService, TitreAdminService>();
|
builder.Services.AddScoped<ITitreAdminService, TitreAdminService>();
|
||||||
|
|
||||||
|
builder.Services.AddScoped<ValidationActionFilter>();
|
||||||
|
builder.Services.AddScoped<GlobalExceptionFilter>();
|
||||||
|
|
||||||
// https://learn.microsoft.com/fr-fr/aspnet/core/performance/response-compression?view=aspnetcore-10.0#configuration
|
// https://learn.microsoft.com/fr-fr/aspnet/core/performance/response-compression?view=aspnetcore-10.0#configuration
|
||||||
// Ajoute le service de compression des réponses HTTP pour réduire la taille des données envoyées au client et améliorer les performances de l'application.
|
// Ajoute le service de compression des réponses HTTP pour réduire la taille des données envoyées au client et améliorer les performances de l'application.
|
||||||
builder.Services.AddResponseCompression();
|
builder.Services.AddResponseCompression();
|
||||||
|
|||||||
@@ -133,8 +133,7 @@
|
|||||||
<textarea name="Contenu"
|
<textarea name="Contenu"
|
||||||
rows="3"
|
rows="3"
|
||||||
class="form-control input-full"
|
class="form-control input-full"
|
||||||
placeholder="Votre commentaire..."
|
placeholder="Votre commentaire..."></textarea>
|
||||||
required></textarea>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -156,7 +155,7 @@
|
|||||||
|
|
||||||
<h4 class="mb-4">Commentaires</h4>
|
<h4 class="mb-4">Commentaires</h4>
|
||||||
|
|
||||||
@if (Model.Details.Commentaires != null && Model.Details.Commentaires.Any())
|
@if (Model.Details.Commentaires.Any())
|
||||||
{
|
{
|
||||||
foreach (var comment in Model.Details.Commentaires.OrderByDescending(c => c.DateCreation))
|
foreach (var comment in Model.Details.Commentaires.OrderByDescending(c => c.DateCreation))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
<div class="d-flex align-items-start my-3">
|
<div class="d-flex align-items-start my-3">
|
||||||
|
|
||||||
<!-- Image -->
|
<!-- Image -->
|
||||||
<a asp-action="Details"
|
<a asp-action="Index"
|
||||||
asp-route-id="@titre.IdTitre"
|
asp-route-id="@titre.IdTitre"
|
||||||
class="me-3 text-black">
|
class="me-3 text-black">
|
||||||
<img src="@titre.UrlJaquette" alt="@titre.Libelle" width="70px" height="70px" class="object-fit-cover" loading="lazy"/>
|
<img src="@titre.UrlJaquette" alt="@titre.Libelle" width="70px" height="70px" class="object-fit-cover" loading="lazy"/>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
@titre.ArtisteNom
|
@titre.ArtisteNom
|
||||||
</a>
|
</a>
|
||||||
-
|
-
|
||||||
<a asp-action="Details"
|
<a asp-action="Index"
|
||||||
asp-route-id="@titre.IdTitre">
|
asp-route-id="@titre.IdTitre">
|
||||||
@titre.Libelle
|
@titre.Libelle
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@
|
|||||||
layout="${longdate}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|${aspnet-request-url:whenEmpty=NoRequest}" />
|
layout="${longdate}|${level:uppercase=true}|${logger}|${message} ${exception:format=tostring}|${aspnet-request-url:whenEmpty=NoRequest}" />
|
||||||
|
|
||||||
<!-- Console pour debug immédiat -->
|
<!-- Console pour debug immédiat -->
|
||||||
<target xsi:type="Console" name="Info"
|
<target xsi:type="Console" name="console"
|
||||||
layout="${longdate}|${level:uppercase=true}|${logger}|${message}" />
|
layout="${longdate}|${level:uppercase=true}|${logger}|${message}" />
|
||||||
</targets>
|
</targets>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user