Asp.net core: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection
I am developing a web api project. Nowadays, I have a problem when calling an endpoint. I do not constantly get an error when calling this endpoint, for example if I am calling 30 times a day, I get this error 2 times. This endpoint just select the data and working async. I tried all the solutions I found on the internet but it didn't work. Error: Cannot access a disposed object. A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<MyContext>(options => options.UseMySql(Environment.GetEnvironmentVariable("MY_DB_CONNECTION")), ServiceLifetime.Transient);
services.DIRegisterer();
}
public static IServiceCollection DIRegisterer(this IServiceCollection services)
{
services.AddScoped<MyService>();
}
Note: I'm using .net core 3.1
1 answer
-
answered 2021-03-08 19:48
Steven
As this problem only shows sporadically, a likely cause of the problem is an (accidental) spawn background operation running parallel to the request operation. This parallel operation has access to the request's
DbContext
instance.NOTE: In case the error would persist after an initial successful operation, this would be an indication that the
DbContext
is held captive by one of its consumers; in other words, a Captive Dependency.In most cases the background operation finishes before the request ends, and thus before the
DbContext
is disposed of. In some cases, however, there is a delay in that (accidental) parallel operation, causing it to access theDbContext
after the request has ended, and thus after theDbContext
was disposed of by ASP.NET Core.This might have happened because you forgot to
await
an asynchronous operation. When you forget toawait
such operation, it starts running in parallel. Running such code in parallel, however, is often problematic, especially when dealing with objects such asDbContext
, as they are not thread-safe.So analyze the stack trace to find the place where you forgot to
await
the operation. For instance:public async Task DoSomethingAsync() { await this.DoSomethingNiceAsync(); this.DoSomethingElseAsync(); // forgot to await } private async Task DoSomethingElseAsync() { // Makes use of dbcontext await this.dbContext.GetEntitiesAsync(); }
See also questions close to this topic
-
Filter items in a listbox that have been added with json
Well I'm trying to list items that are from listbox created with UserControl and the text properties are defined with a json file.
This is my .json file:
{ "Games": { "Quantity": 2, "Title0": "SomeGame1", "Description0": "Fps game", "Image0": "Some image link", "Link0": "GameStore.com/Somegame1", "Title1": "SomeGame2", "Description1": "RPG game", "Image1": "Some image link", "Link1": "GameStore.com/Somegame2", } }
This is the code to load the games as items in the listbox:
string JsonFile = Environment.CurrentDirectory @"\Test.json"; dynamic jasonfile = JsonConvert.DeserializeObject(JsonFile); GameUserControl[] Games = new GameUserControl[jasonfile["Games"]["Quantidade"]]; for (int quantity= 0; quantity < Games.Length; quantity++) { Games[quantity] = new GameUserControl(); Games[quantity].Descrição.Content = (jasonfile["Games"]["Title" + quantity]); Games[quantity].jog = (jasonfile["Games"]["Titulo" + quantity]); Games[quantity].lin = (jasonfile["Games"]["Link" + quantity]); string image = jasonfile["Games"]["Image" + quantity]; Games[quantity].imag = new ImageBrush(new BitmapImage(new Uri(image, UriKind.Absolute))); GamesListBox.Items.Add(Games[quantity]); }
This is the code I used in a textbox to try to filter:
if (CollectionViewSource.GetDefaultView(GamesListBox.Items) != null) CollectionViewSource.GetDefaultView(GamesListBox.Items).Filter = (o) => { return o.ToString().ToLower().Contains(Search.Text.ToLower()); };
But it didn't work, the item names are always GameUserContro.Can someone help me?
-
Advantage of .Net Core over WCF for RESTful APIs
We are currently using WCF to create RESTful APIs, it is working fine and has an added advantage that it can be consumed via SOAP too if we ever need to. We have all our systems using Microsoft technologies.
There is no active development on WCF but the current functionality is working fine for us. However, I believe the recommended approach is to start using .Net core for RESTful services. What are the additional advantages .Net core offers over WCF (apart from being platform independent)?
-
Generic class type constraint with a generic class having another constraint
Let's say I have a generic class
public class G<T> { }
and I want to declare final class as
public class F<T> where T : G<T> { }
that seems to be possible, but what if I want to complicate the task and add a constraint to the class G like that
public class A { } public class DA : A { } public class DB : A { } public class G<T> where T : A { }
and finally I want to do this
public class F<T> where T : G<T> { }
that does not work, it says T has to be of type A which is understandable and it looks like I can rewrite it like this
public class F<T, U> where T : G<U> where U : A { }
but in this case the usage has a redundant declaration
public class DF : F<G<DA>, DA> { }
I have to repeat DA twice when using class F even though it is quite clear if I use G as a generic type the generic type of G is DA. Is there a way to avoid this redundancy?
-
Trouble with search functionality in ASP.NET Core MVC
I am trying to add a search functionality to my website. I have managed to add some of the search criteria that i needed however now the data in one of the columns called
Departments
in not showing for some reason. I think it might be due to there being two tables rather than one. Below is the code for my search function along with a screenshot of my problem.Edit1 I have tried implementing lazy include like suggested so here is the code now, I have also attached a picture of my new error.
public async Task<IActionResult> SList(string search) { ViewData["GetStudentDetails"] = search; var studentquery = from x in _Db.tbl_Student.Include("tbl_Departments") select x; if(!String.IsNullOrEmpty(search)) { studentquery = studentquery.Where(x => x.FirstName.Contains(search) || x.Email.Contains(search)); } return View(await studentquery.AsNoTracking().ToListAsync()); }
Edit2 I have also tried writing "Departments" only as suggested but i still get the same error.
-
NotMapped property is not supported in Linq?
I have added RunCount property in class and called in function as below.
public class ItemsDataObject { [Key] [Column("ID")] public string Id{ get; set; } . . . [NotMapped] public int RunCount { get; set; } } public static List<ItemsDataObject> GetAllItemsWithPaging(int startingPageIndex, int pageSize, string orderColumn, string orderDir) { using (var ctx = new OracleDbContext()) { List<ItemsDataObject> list = new List<ItemsDataObject>(); var v = (from a in ctx.Items select a); v = v.OrderBy(orderColumn + " " + orderDir); list = v.Skip(startingPageIndex).Take(pageSize).ToList(); return list; } }
There are large data in list so i need to firstly sort items and get 10 rows(pagesize) and then .ToList().
But i am getting System.NotSupportedException error. How can i fix the issue?
The specified type member 'RunCount' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported.
-
EF Core 5 - Update an entity with SQL does not work
I have an application that use EF Core 5 with SQL Server for production/dev and SQLLite for integration tests.
In SQL server all works perfectly but with SQLLite in my test my entity is not updated.
Let's go with some code and explanation.
Model Buidler
Here my model builder configuration for my entity :
modelBuilder.Entity<Order>(order => { order.ToTable("Orders"); order.HasKey(s => s.Id); order.Property(i => i.ConcurrencyStamp).IsRowVersion(); order.Property(i => i.ShippingExcludingTaxes).HasColumnType("decimal(10,2)"); order.Property(i => i.ShippingIncludingTaxes).HasColumnType("decimal(10,2)"); order.HasMany(s => s.OrderItems).WithOne() .Metadata.PrincipalToDependent.SetPropertyAccessMode(PropertyAccessMode.Field); order.Metadata.FindNavigation(nameof(Order.OrderItems)).SetPropertyAccessMode(PropertyAccessMode.Field); order.HasOne<Payment>(p => p.Payment) .WithOne() .HasForeignKey<Order>(p => p.PaymentId); order.HasOne<Address>(s => s.ShippingAddress) .WithOne() .HasForeignKey<Order>(p => p.ShippingAddressId); order.OwnsOne(lc => lc.Contact); });
I already read that RowVersion does not work like in SQLServer, here I use a string generated by a Guid and here the code to update it in each savechanges ( classic & async ):
private void UpdateLastUpdate() { var entries = ChangeTracker .Entries() .Where(e => e.Entity is Entity && ( e.State == EntityState.Added || e.State == EntityState.Modified)); foreach (var entityEntry in entries) { ((Entity)entityEntry.Entity).LastUpdate = DateTime.Now; ((Entity)entityEntry.Entity).ConcurrencyStamp = Guid.NewGuid().ToString(); } }
Domain class & Tested method
Here is my entity that I want to update
public class Order : Entity, IAggregateRoot { public string UserId { get; set; } public decimal ShippingIncludingTaxes { get; set; } public decimal ShippingExcludingTaxes { get; set; } public OrderState State { get; set; } public string PaymentId { get; set; } public Payment Payment{ get; set; } private readonly List<OrderItem> _orderItems = new List<OrderItem>(); public IReadOnlyCollection<OrderItem> OrderItems => _orderItems; public string ShippingAddressId { get; set; } public Address ShippingAddress { get; set; } public OrderContact Contact { get; set; } public ICollection<OrderHistory> OrderHistories { get; set; } public decimal TotalIncludingTaxes => _orderItems.Sum(s => s.TotalIncludingTaxes) + ShippingIncludingTaxes; //some other stuff }
and the attributes that I am updating In my test
//method is in Order.cs public void SetInProgress(OrderHistory history) { State = OrderState.InProgress; OrderHistories = OrderHistories ?? new List<OrderHistory>(); OrderHistories.Add(history); }
Test and assert
So I run my integration test, all works and I see that my DBContext take my changes. But when It comes to make the assert, the entity is the same before the test
public class OrderControllerTest : IClassFixture<IntegrationTestFixture> { private readonly IntegrationTestFixture _fixture; public OrderControllerTest(IntegrationTestFixture fixture) { _fixture = fixture; Init().GetAwaiter().GetResult(); } private IRepository<OrderHistory, UserContext> _orderHistoryRepository; private IRepository<Nursery, PlantContext> _nurseryRepository; private IRepository<Order, UserContext> _orderRepository; private Nursery nursery; private async Task Init() { _orderHistoryRepository = _fixture.Services.GetService<IRepository<OrderHistory, UserContext>>(); _nurseryRepository = _fixture.Services.GetService<IRepository<Nursery, PlantContext>>(); _orderRepository = _fixture.Services.GetService<IRepository<Order, UserContext>>(); nursery = await _nurseryRepository.FindAsync(a => a.LegalNumber == NurseryService.LEPAGE_LEGALNUMBER); } [Fact] [Trait("Category", "Integration")] public async Task OrderController_SendOrders_ShouldBeOkWithOrders() { await _orderRepository.AddAsync(OrderGenerator.GenerateOrder(OrderState.Validated, nursery.Id)); var result = await _fixture.GetAsync("api/order/send"); result.IsSuccessStatusCode.Should().BeTrue(); var histories = await _orderHistoryRepository.FilterAsync(s => true); var orders = await _orderRepository.FilterAsync(s => true); histories.Should().NotBeEmpty(); orders.All(all => all.State == OrderState.InProgress).Should().BeTrue(); } }
Here when I test if my orders have InProgress state, the result is false because the State is Validated ( the state does not change since the creation ).
If somebody have an idea ? If the error occurred because of the Guid row version, if any configuration exist to make my test working ?
-
Cors error missing allow origin header. MailKit
I have
cors error missing allow origin header
error only on ONE post request. My CORS Policypublic void ConfigureServices(IServiceCollection services) { services.AddCors(options => { options.AddPolicy("AllowAllOrigins", builder => { builder.SetIsOriginAllowed(_ => true) .AllowAnyHeader() .AllowAnyMethod() .AllowCredentials(); }); }); }
Every request work fine, but one POST request fails, it's really weird. Code in controller action which failed use MailKit and SMTP to send email, maybe that's cause
-
The entity type was not found. Ensure that the entity type has been added to the model
I'm new to ASP.NET Core and i'm trying to insert an entity into an Entity Framework Core model scaffolded from a simple existing MariaDB database.
This is the entity model:
public class ScrapeAsincroni { public int Id { get; set; } public string Paese { get; set; } public string Engine { get; set; } public string Keywords { get; set; } }
This is the controller action that is supposed to add the entity:
public JsonResult create(string paese, string engine, string keywords) { ScrapeAsincroni scrapeAsincrono = new ScrapeAsincroni { Paese = paese, Engine = engine, Keywords = keywords }; _context.Add(scrapeAsincrono); try { _context.SaveChangesAsync(); } catch (Exception ex) { return Json(new Dictionary<string, int?> { { "id", null } }); } return Json(new Dictionary<string, int?>{ {"id", scrapeAsincrono.Id} }); }
The database context (_context) has been initialized on the controller's constructor. the line
_context.Add(scrapeAsincrono);
throws the following exception:
System.InvalidOperationException: The entity type 'ScrapeAsincroni' was not found. Ensure that the entity type has been added to the model.
This is the modelBuilder code relative to this model
public partial class ScraperDbContext : DbContext { public ScraperDbContext() { } public ScraperDbContext(DbContextOptions<ScraperDbContext> options) : base(options) { } public virtual DbSet<ScrapeAsincroni> ScrapeAsincroni { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { if (!optionsBuilder.IsConfigured) { #warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings. optionsBuilder.UseMySql("server=51.255.74.100;port=3306;user=luca.ceccagnoli;password=Hb93#2ql;database=scraper_db", x => x.ServerVersion("10.3.25-mariadb")); } } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<ScrapeAsincroni>(entity => { entity.HasComment("Informazioni su una ricerca asincrona dello Scraper"); entity.Property(e => e.Id) .HasColumnName("id") .HasColumnType("int(11)"); entity.Property(e => e.Engine) .HasColumnName("engine") .HasColumnType("varchar(255)") .HasCharSet("utf8") .HasCollation("utf8_general_ci"); entity.Property(e => e.Keywords) .IsRequired() .HasColumnName("keywords") .HasColumnType("text") .HasCharSet("utf8") .HasCollation("utf8_general_ci"); entity.Property(e => e.Paese) .HasColumnName("paese") .HasColumnType("varchar(255)") .HasCharSet("utf8") .HasCollation("utf8_general_ci"); }); OnModelCreatingPartial(modelBuilder); } partial void OnModelCreatingPartial(ModelBuilder modelBuilder); }
I can't seem to understand why this happens, and couldn't find any solutions online.
-
Unique Id for .Net Core actions
I need to have an ID for my actions to save them in DB and retrieve them for security issues. I thought this is a unique and constant Id but it is different in every run:
var items = _actionDescriptorCollectionProvider .ActionDescriptors.Items .OfType<ControllerActionDescriptor>() .Select(a => new { a.ControllerName, a.ActionName, a.Id })
Any idea for a unique and fixed ID for each action?
-
Retrieving the injector instance in a Play 2.8 application
I am migrating a Play Application from 2.4 to 2.8. I have been successful adapting the application and it runs to some degree, but I am currently stuck with a call to the injector.
The current code reads:
private final TestDB testdb = play.api.Play.current().injector().instanceOf(TestDB.class);
which was the recommended way to go in earlier versions of Play. However, play.Play and play.api.Play have been deprecated since version 2.5: https://www.playframework.com/documentation/2.8.x/Migration25#Deprecated-play.Play-and-play.api.Play-methods
The next option would be using the guice DI as the migration guide explains by using @Inject, which was already used and working in most of the application. However, from what I understand "Injection from a custom class, which is not injected by itself, should be done by explicit call to the injector" (http://www.codepreference.com/2016/07/guice-dependency-injection-in-play.html) and if I try, then indeed the dependencies are not injected and null is given for those variables. So, if I understand correctly, @Inject is not an option since the class is instanciated outside of the injection mechanisms (in accordance to what I see in the code, it uses "new")
Since it was mentioned on forums, I tried:
@Inject private play.api.inject.Injector injector; private final TestDB testdb = injector.instanceOf(TestDB.class);
which obviously doesn't work either, since nothing gets injected, including the Injector.
A parent instance (x calls up) does inject these dependences and as a solution I could pass them along, but I feel there must be a more elegant solution to this. So my actual question is: Is there a way in Play 2.8 to retrieve the injector instance that is used by the application?
Maybe I am missing something very simple, I am rather new to Play and Guice DI, so any help would be greatly appreciated. All the solutions that I found online refer to older versions of play, which do allow direct access to the injector or application objects. The examples from play 2.8 also show how to retrieve the injector, but only in the context of (unit) testing. Also, it is written primarily in Java, rather than Scala.
-
Cannot resolve dependency using unity container when application pool recycles
When application pool recycles, i am facing an issue with one of our dependency that fails to resolve. When we recycle again it resolves correctly. I have written log at some points details below,
The current type, MyApp.DataAccess.IDataAccess, is an interface and cannot be constructed. Are you missing a type mapping?\r At the time of the exception, the container was:\r\n\r\n Resolving MyApp.DataAccess.IDataAccess,(none)\r\n","DBResponseId":0} Microsoft.Practices.Unity.ResolutionFailedException Resolution of the dependency failed, type = "MyApp.DataAccess.IDataAccess", name = "(none)". Exception occurred while: while resolving. Exception is: InvalidOperationException - The current type, MyApp.DataAccess.IDataAccess, is an interface and cannot be constructed. Are you missing a type mapping? ----------------------------------------------- At the time of the exception, the container was: Resolving MyApp.DataAccess.IDataAccess,(none) at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) at Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) at Microsoft.Practices.Unity.UnityContainerExtensions.Resolve[T](IUnityContainer container, ResolverOverride[] overrides) at MyApp.Services.ServiceHelper.GetSession(String token, Boolean updateLastRequestTime) in E:\Application\MyAlert\Web\MyAlertCloud-Dev\Services\Services\ServiceHelper.cs:line 154 at MyApp.ServiceFacade.BaseServiceFacade`1.ExecuteService[TRequest,TResponse](Func`3 serviceFunc, TRequest request) in E:\Application\MyAlert\Web\MyAlertCloud-Dev\Services\Facade\ServiceFacade\BaseServiceFacade.cs:line 164 ------------------------------ INNER LEVEL 1------------------------------ System.InvalidOperationException The current type, MyApp.DataAccess.IDataAccess, is an interface and cannot be constructed. Are you missing a type mapping? at Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.ThrowForAttemptingToConstructInterface(IBuilderContext context) at BuildUp_MyApp.DataAccess.IDataAccess(IBuilderContext ) at Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) at Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) at Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides)
Here is how the configurations are done in unity config
<typeAlias alias="IDataAccess" type="MyApp.DataAccess.IDataAccess, MyApp.DataAccess" /> <typeAlias alias="DataAccess" type="MyApp.DataAccess.DataAccess, MyApp.DataAccess" />
The behaviour is on and off. Which is very strange.
-
How to resolve "Unable to construct some services error"?
I want to use AddDataloader method from hot chocolate and it requires me to use AddPooledDbContextFactory. I previously used AddDbContext with a singleton lifetime and registered singleton repositories. How can i still register my repos as singleton? These repos have a dependency on the AppdDbContext so its giving me an error that services cannot be constructed.