【问题标题】:ASP.NET Core 2.1 MVC - Log Each Request to DatabaseASP.NET Core 2.1 MVC - 将每个请求记录到数据库
【发布时间】:2019-01-03 00:44:45
【问题描述】:

我想记录我的应用处理每个请求所花费的时间,以及一些其他信息,例如收到的每个请求的 IP 地址。

我在 Startup.cs 添加了一个 app.Use 步骤 -> 使用依赖注入配置到我的 dbcontext。当以下代码触发并且我的 MVC 管道似乎正确触发时,我没有收到任何错误。

问题是任何涉及 dbcontext 的调用似乎都会退出代码。在下面的示例中,db.PageRequests.Add(pageRequest); 导致代码退出。该页面仍然可以正常呈现,但当然缺少响应附加的任何内容。

我不禁认为这是一个异步/线程问题,但我迷失了想法。我还尝试使 dbcontext 交互同时同步和异步,但它没有帮助。

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ApplicationDbContext db)
    {
        app.Use(async (context, next) =>
        {
            var sw = new Stopwatch();
            sw.Start();
            await next.Invoke();
            sw.Stop();

            PageRequest pageRequest = new PageRequest()
            {
                ipAddress = context.Connection.RemoteIpAddress.ToString(),
                loadTime = sw.ElapsedMilliseconds
            };
            db.PageRequests.Add(pageRequest);  // this code exits and page is rendered.  Code below here is never fired.
            db.SaveChanges();

            await context.Response.WriteAsync("<p>" + sw.ElapsedMilliseconds.ToString() + "<p>");
            await context.Response.WriteAsync("<p>" + context.Connection.RemoteIpAddress + "<p>");
            await context.Response.WriteAsync("<p>" + context.Request.Host + context.Request.Path + context.Request.QueryString + "<p>");

        });
    // other app.use statements here
    }

【问题讨论】:

    标签: entity-framework logging asp.net-core-mvc configure asp.net-core-2.1


    【解决方案1】:

    我在Microsoft Documentation 中发现了一条评论,它为我指明了正确的方向。

    因为中间件是在应用启动时构建的,而不是按请求构建的,所以中间件构造函数使用的作用域生命周期服务不会在每个请求期间与其他依赖注入类型共享。如果您必须在中间件和其他类型之间共享范围服务,请将这些服务添加到 Invoke 方法的签名中。

    我相信注入到 Configure 方法中的 dbcontext 在应用程序启动后不再可用,因此在每个请求期间都无法访问。 令人沮丧的是,这并没有引发错误。

    解决方案是将中间件委托移动到一个类并在调用方法中注入上下文。

    这是对我有用的代码:

    public class Logging
    {
        private readonly RequestDelegate _next;
    
        public Logging(RequestDelegate next)
        {
            _next = next;
        }
    
        public async Task InvokeAsync(HttpContext context, ApplicationDbContext db)
        {
            var sw = new Stopwatch();
            sw.Start();
            await _next(context);
            sw.Stop();
    
            PageRequest pageRequest = new PageRequest()
            {
                ipAddress = context.Connection.RemoteIpAddress.ToString(),
                loadTime = sw.ElapsedMilliseconds
            };
            await db.PageRequests.AddAsync(pageRequest); 
            db.SaveChanges();
    
            await context.Response.WriteAsync("<p>" + sw.ElapsedMilliseconds.ToString() + "<p>");
            await context.Response.WriteAsync("<p>" + context.Connection.RemoteIpAddress + "<p>");
            await context.Response.WriteAsync("<p>" + context.Request.Host + context.Request.Path + context.Request.QueryString + "<p>");
        }
    
    }
    
    public static class LoggingMiddlewareExtensions
    {
        public static IApplicationBuilder UseLogging(
            this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<Logging>();
        }
    }`
    

    然后您可以将 Use 语句添加到 Startup.cs -> 配置

        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ApplicationDbContext db)
        {
    
            app.UseLogging();
    
        }
    

    【讨论】:

      猜你喜欢
      • 2017-12-24
      • 1970-01-01
      • 1970-01-01
      • 2019-02-12
      • 1970-01-01
      • 2020-08-13
      • 1970-01-01
      • 2019-04-12
      • 1970-01-01
      相关资源
      最近更新 更多