ASP.NET Core 2.1 MVC - регистрировать каждый запрос к базе данных - PullRequest
0 голосов
/ 02 января 2019

Я хочу, чтобы база данных регистрировала время, необходимое моему приложению для обработки каждого запроса, и некоторую другую информацию, такую ​​как IP-адреса для каждого полученного запроса.

Я добавил приложение. Используйте шаг в Startup.cs-> Сконфигурировать с внедрением зависимости в мой 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
    }

1 Ответ

0 голосов
/ 02 января 2019

Я нашел комментарий в Документации Microsoft , который указал мне правильное направление.

Поскольку промежуточное ПО создается при запуске приложения, а не по запросу, сервисы времени действия с областью действияиспользуемые конструкторами промежуточного программного обеспечения не используются совместно с другими типами, внедренными зависимостями, во время каждого запроса.Если вы должны совместно использовать сервис с определенной областью между промежуточным программным обеспечением и другими типами, добавьте эти сервисы в подпись метода Invoke.

Я полагаю, что dbcontext, введенный в метод Configure, больше не доступен после запуска приложения и, следовательно, недоступен при каждом запросе. Обидно, что это не вызвало ошибку.

Решением было переместить делегат промежуточного программного обеспечения в класс и вставить контекст в метод invoke.

Вот код, который работал для меня:

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 -> Configure

    public void Configure(IApplicationBuilder app, IHostingEnvironment env, ApplicationDbContext db)
    {

        app.UseLogging();

    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...