BCards/src/BCards.Web/Areas/Tutoriais/Controllers/TutoriaisController.cs

112 lines
3.5 KiB
C#

using BCards.Web.Areas.Tutoriais.Models;
using BCards.Web.Areas.Tutoriais.Services;
using BCards.Web.Repositories;
using Microsoft.AspNetCore.Mvc;
namespace BCards.Web.Areas.Tutoriais.Controllers;
[Area("Tutoriais")]
public class TutoriaisController : Controller
{
private readonly IMarkdownService _markdownService;
private readonly ICategoryRepository _categoryRepository;
private readonly ILogger<TutoriaisController> _logger;
public TutoriaisController(
IMarkdownService markdownService,
ICategoryRepository categoryRepository,
ILogger<TutoriaisController> logger)
{
_markdownService = markdownService;
_categoryRepository = categoryRepository;
_logger = logger;
}
// GET /tutoriais
public async Task<IActionResult> Index()
{
var categories = await _categoryRepository.GetAllActiveAsync();
var tutoriaisPorCategoria = new Dictionary<string, List<ArticleMetadata>>();
foreach (var category in categories)
{
var artigos = await _markdownService
.GetArticlesByCategoryAsync(category.Slug, "pt-BR");
if (artigos.Any())
{
tutoriaisPorCategoria[category.Slug] = artigos;
}
}
ViewBag.Categories = categories;
return View(tutoriaisPorCategoria);
}
// GET /tutoriais/{categoria}
public async Task<IActionResult> Category(string categoria)
{
// Validar categoria existe
var category = await _categoryRepository.GetBySlugAsync(categoria);
if (category == null)
{
_logger.LogWarning("Categoria não encontrada: {Categoria}", categoria);
return NotFound();
}
var artigos = await _markdownService
.GetArticlesByCategoryAsync(categoria, "pt-BR");
ViewBag.Category = category;
return View(artigos);
}
// GET /tutoriais/{categoria}/{slug}
public async Task<IActionResult> Article(string categoria, string slug)
{
// Sanitização (segurança contra path traversal)
categoria = categoria.Replace("..", "").Replace("/", "").Replace("\\", "");
slug = slug.Replace("..", "").Replace("/", "").Replace("\\", "");
// Validar categoria existe
var category = await _categoryRepository.GetBySlugAsync(categoria);
if (category == null)
{
_logger.LogWarning("Categoria não encontrada: {Categoria}", categoria);
return NotFound();
}
try
{
var article = await _markdownService.GetArticleAsync(
$"Tutoriais/{categoria}/{slug}",
"pt-BR"
);
if (article == null)
{
_logger.LogWarning("Artigo não encontrado: {Categoria}/{Slug}", categoria, slug);
return NotFound();
}
// Buscar artigos relacionados da mesma categoria
article.RelatedArticles = await _markdownService
.GetArticlesByCategoryAsync(categoria, "pt-BR");
// Remover o artigo atual dos relacionados
article.RelatedArticles = article.RelatedArticles
.Where(a => a.Slug != slug)
.Take(3)
.ToList();
ViewBag.Category = category;
return View(article);
}
catch (FileNotFoundException)
{
_logger.LogWarning("Arquivo markdown não encontrado: {Categoria}/{Slug}", categoria, slug);
return NotFound();
}
}
}