










中间件适用于所有请求,它可以在请求进入 Controller 之前执行统计操作。
VisitMiddlewarepublic class VisitMiddleware
{
private readonly RequestDelegate _next;
private readonly IServiceScopeFactory _scopeFactory;
private readonly TimeSpan _timeSpan = TimeSpan.FromHours(1);
public VisitMiddleware(RequestDelegate next, IServiceScopeFactory scopeFactory)
{
_next = next;
_scopeFactory = scopeFactory; // 用于创建独立的 `DbContext`
}
public async Task InvokeAsync(HttpContext context)
{
using (var scope = _scopeFactory.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
string ipAddress = context.Connection.RemoteIpAddress?.ToString() ?? "Unknown";
string pageUrl = context.Request.Path;
var oneHourAgo = DateTime.Now - _timeSpan;
var existingVisit = dbContext.PageVisits
.Where(v => v.IpAddress == ipAddress && v.PageUrl == pageUrl && v.VisitTime >= oneHourAgo)
.FirstOrDefault();
if (existingVisit == null)
{
dbContext.PageVisits.Add(new PageVisit
{
IpAddress = ipAddress,
PageUrl = pageUrl,
VisitTime = DateTime.Now
});
await dbContext.SaveChangesAsync();
}
}
await _next(context); // 继续执行后续请求
}
}
在 Program.cs 添加:
app.UseMiddleware<VisitMiddleware>();
ActionFilterActionFilter 适用于 Controller 层,它比中间件更灵活,可以指定仅在某些 Controller 或 Action 上执行。
VisitActionFilterusing Microsoft.AspNetCore.Mvc.Filters;
public class VisitActionFilter : IActionFilter
{
private readonly IServiceScopeFactory _scopeFactory;
private readonly TimeSpan _timeSpan = TimeSpan.FromHours(1);
public VisitActionFilter(IServiceScopeFactory scopeFactory)
{
_scopeFactory = scopeFactory;
}
public void OnActionExecuting(ActionExecutingContext context)
{
using (var scope = _scopeFactory.CreateScope())
{
var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();
string ipAddress = context.HttpContext.Connection.RemoteIpAddress?.ToString() ?? "Unknown";
string pageUrl = context.HttpContext.Request.Path;
var oneHourAgo = DateTime.UtcNow - _timeSpan;
var existingVisit = dbContext.PageVisits
.Where(v => v.IpAddress == ipAddress && v.PageUrl == pageUrl && v.VisitTime >= oneHourAgo)
.FirstOrDefault();
if (existingVisit == null)
{
dbContext.PageVisits.Add(new PageVisit
{
IpAddress = ipAddress,
PageUrl = pageUrl,
VisitTime = DateTime.UtcNow
});
dbContext.SaveChanges();
}
}
}
public void OnActionExecuted(ActionExecutedContext context) { }
}
ActionFilter在 Program.cs 中:
services.AddScoped<VisitActionFilter>();
然后,在 Controller 中使用:
[ServiceFilter(typeof(VisitActionFilter))]
public class MyController : ControllerBase
{
// 所有请求自动记录访问
}
中间件 (Middleware) 适用于 所有请求,不会局限于某个 Controller。
过滤器 (ActionFilter) 适用于 特定的 Controller 或 Action,如果你不想记录所有页面,可以选择这个方案。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。