question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Data cached in custom middleware

See original GitHub issue

I’m using ASP.NET Core 1.1.0 and EF Core 1.1.0. I extended the built-in JWT Bearer authentication with my own middleware, but data is being cached between calls. I have a feeling the DB context is being reused, but I’m not sure how to troubleshoot.

Specifically, I’m calling the token endpoint to invoke the middleware and get a new JWT. The user is returned, all is good. If I manually update the DB with SSMS then log in again, the old, outdated user information is returned. The DB is being hit both times and it’s returning the correct data (I verified with SQL Profiler), but EF is apparently ignoring the updated data in favor of what it already had.

I’m using standard DI with the token middleware, nothing special there. Relevant code is below.

Startup.cs:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<MyContext>(options =>
        options.UseSqlServer(Environment.GetEnvironmentVariable("DEV_CONNECTIONSTRING")));

    services.AddScoped<UserService>();
}

public void Configure(IApplicationBuilder app,
                      IHostingEnvironment env,
                      ILoggerFactory loggerFactory,
                      IApplicationLifetime appLifetime)

    /* These options specify:
    * - token endpoint
    * - authentication scheme
    * - JWT issuer
    * - duration of JWT validity
    * - duration of refresh token validity */
    app.UseMiddleware<JwtProviderMiddleware>(new JwtProviderOptions(
        "/api/users/token",
        "Bearer",
        "MyJwtIssuer",
        Duration.FromMinutes(30),
        Duration.FromDays(7)
    ));
}

Custom JWT provider middleware:

public class JwtProviderMiddleware
{
    readonly RequestDelegate _next;
    readonly JwtProviderOptions _options;
    readonly UserService _userSvc;

    public JwtProviderMiddleware(RequestDelegate next,
                                 JwtProviderOptions options,
                                 UserService userSvc)
    {
        _next = next;
        _options = options;
        _userSvc = userSvc;
    }

    public async Task Invoke(HttpContext context)
    {
        // parse request body for email address and password
        
        // user is returned incorrectly here
        var user = await _userSvc.GetByEmailAsync(email);
    }
}

UserService:

public class UserService
{
    MyContext _context;

    public UserService(MyContext context)
    {
        _context = context;
    }

    public async Task<User> GetByEmailAsync(string email)
    {
        return await _context.Users.FirstOrDefaultAsync(u => u.Email == email);
    }
}

Further technical details

EF Core version: 1.1.0 Database Provider: Microsoft.EntityFrameworkCore.SqlServer Operating system: Windows 10 Education x64 IDE: VS 2015 Enterprise

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:6 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
vaindilcommented, Jan 5, 2017

@tuespetre Shoot, good catch! I have a couple other functions in this middleware that are called by Invoke(), that’s why I was using a field. I altered them to accept a UserService parameter and I’m passing the local variable now.

Thanks again!

1reaction
tuespetrecommented, Jan 5, 2017

You should use a local variable instead of a field to store the user service, otherwise your code is not thread-safe: request A begins and sets the field, but before it gets to the last line, request B begins and overwrites the field. Now when A gets to the last line, it’s seeing the value written by request B.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Response Caching Middleware in ASP.NET Core
The middleware determines when responses are cacheable, stores responses, and serves responses from cache. For an introduction to HTTP caching ...
Read more >
Output caching middleware in ASP.NET Core
This article explains how to configure output caching middleware in an ASP.NET Core app. For an introduction to output caching, see Output ...
Read more >
Custom response caching in ASP.NET Core (with ... - DevTrends
This post outlined how to create basic response caching middleware which allows you to manually invalidate entries both individually and in bulk using...
Read more >
Exploring the new output caching middleware
The most basic way to do this is by using the CacheOutput extension to an IEndpointRouteBuilder (a route).
Read more >
Net Core Custom Response Cache
1 Answer. You can create a custom middleware for that scenario, which reads the boolean value from the query and caches the response...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found