using System.ComponentModel.DataAnnotations;
using System.Text.RegularExpressions;
using Dpz.Core.Service.Mediator.Features.Article.Queries;
using Dpz.Core.Web.Library.Api;
namespace Dpz.Core.Web.Controllers;
public partial class ArticleController(IArticleService articleService, IMediator mediator)
: Controller
{
public async Task<IActionResult> Index(
[FromServices] IHomeCacheService cacheService,
[PageMetadataParameter] string? tag = "",
[Range(10, 100)] int pageSize = 10,
int pageIndex = 1,
CancellationToken cancellationToken = default
)
{
if (!ModelState.IsValid)
{
return NotFound();
}
var tags = string.IsNullOrEmpty(tag) ? [] : new[] { tag };
this.SetTitle(string.IsNullOrEmpty(tag) ? "文章列表" : $"标签-{tag}-文章列表");
var list = await articleService.GetPagesAsync(
pageIndex,
pageSize,
tags: tags,
cancellationToken: cancellationToken
);
if (Request.Headers["X-PJAX"] == "true" && Request.Query["_pjax"] == "#article-list")
{
return PartialView("_ArticleListPartial", list);
}
var model = new ArticleIndexModel
{
LikeArticle = await cacheService.GetRandomArticlesAsync(cancellationToken),
List = list,
News = await cacheService.GetLatestArticlesAsync(cancellationToken),
Tags = await cacheService.GetArticleTagsAsync(cancellationToken),
};
return View(model);
}
public async Task<IActionResult> Read(
string id = "",
string text = "",
CancellationToken cancellationToken = default
)
{
var article = await mediator.Send(
new ArticleReadRequest { Id = id, Text = text },
cancellationToken
);
if (article == null)
{
return NotFound();
}
await articleService.ViewAsync(id, cancellationToken);
this.SetTitle(article.Title);
var pageMetaPage = new VmPageMetadata
{
Description = ClearIntroductionRegex().Replace(article.Introduction ?? "", ""),
Keywords = [article.Title],
Relations = ["Article", "Read", id],
};
ViewData["PageMetadata"] = pageMetaPage;
ViewData["Text"] = text;
return View(article);
}
[GeneratedRegex("<[^>]*>")]
private static partial Regex ClearIntroductionRegex();
public async Task<IActionResult> Archive(
int pageIndex = 1,
int pageSize = 50,
CancellationToken cancellationToken = default
)
{
this.SetTitle("文章归档");
var archive = await articleService.GetArchivePagedAsync(
pageIndex,
pageSize,
cancellationToken
);
return View(archive);
}
[HttpGet]
public async Task<IActionResult> ArchiveLoadMore(
int pageIndex = 1,
int pageSize = 50,
CancellationToken cancellationToken = default
)
{
var archive = await articleService.GetArchivePagedAsync(
pageIndex,
pageSize,
cancellationToken
);
return PartialView("_ArchiveItemsPartial", archive);
}
}
⚠⚠ 以下内容为AI分析的结果,请根据实际情况进行判断。
代码解释
这是一个 ASP.NET Core MVC 控制器类,用于处理文章相关的 Web 请求。以下是详细说明:
类定义
public partial class ArticleController(IArticleService articleService, IMediator mediator) : Controller
- 使用 C# 12 的主构造函数语法,直接在类声明中注入依赖
- 依赖注入了
IArticleService(文章服务)和IMediator(中介者模式,用于处理查询/命令) partial关键字表示这是部分类,可能在其他文件中有其他部分
方法详解
1. Index 方法 - 文章列表页
public async Task<IActionResult> Index(...)
功能:显示文章列表,支持按标签筛选和分页
参数:
cacheService: 从 DI 容器注入的缓存服务tag: 标签过滤参数(带自定义特性PageMetadataParameter)pageSize: 每页大小(10-100,默认10)pageIndex: 当前页码(默认1)cancellationToken: 取消令牌
逻辑流程:
- 验证模型状态,无效则返回 404
- 处理标签参数(空字符串转为空数组)
- 设置页面标题
- 获取分页文章列表
- PJAX 支持:如果是 PJAX 请求,仅返回部分视图(局部刷新)
- 否则返回完整视图,包含:
- 随机推荐文章
- 文章列表
- 最新文章
- 标签列表
2. Read 方法 - 文章详情页
public async Task<IActionResult> Read(...)
功能:显示文章详细内容
参数:
id: 文章IDtext: 额外的文本参数cancellationToken: 取消令牌
逻辑流程:
- 通过 Mediator 发送
ArticleReadRequest查询请求 - 文章不存在则返回 404
- 异步增加文章浏览次数
- 设置页面标题
- 构建 SEO 元数据:
- Description: 从文章简介中移除 HTML 标签(使用正则)
- Keywords: 文章标题
- Relations: 关系标识(Article/Read/id)
- 将数据存入 ViewData 并返回视图
3. ClearIntroductionRegex - 正则表达式生成器
[GeneratedRegex("<[^>]*>")]
private static partial Regex ClearIntroductionRegex();
- 使用 .NET 7+ 的源代码生成器特性
- 编译时生成正则表达式,性能更优
- 用于匹配并移除 HTML 标签(
<...>)
4. Archive 方法 - 文章归档页
public async Task<IActionResult> Archive(...)
功能:显示文章归档列表(按时间分组)
参数:
pageIndex: 页码(默认1)pageSize: 每页大小(默认50)
逻辑流程:
- 设置页面标题为"文章归档"
- 获取分页归档数据
- 返回归档视图
5. ArchiveLoadMore 方法 - 归档懒加载
[HttpGet]
public async Task<IActionResult> ArchiveLoadMore(...)
功能:用于"加载更多"功能,返回部分视图
特点:
- 仅支持 GET 请求
- 返回
_ArchiveItemsPartial部分视图 - 用于实现无刷新加载更多归档内容
技术亮点
- 依赖注入: 使用主构造函数简化代码
- CQRS 模式: 通过 Mediator 处理查询
- PJAX 支持: 实现页面局部刷新
- 正则表达式优化: 使用源生成器提升性能
- SEO 友好: 设置页面元数据
- 异步编程: 全部使用异步方法
- 取消令牌: 支持请求取消
- 数据验证: 使用
[Range]等特性
这是一个现代化的、性能优化的 ASP.NET Core 控制器实现。
AI 正在分析代码…
评论加载中...