Reputation: 903
I am getting this error mentioned in the title. The same code works for the first API call, but not for the 2nd call. It fails on the 2nd SaveChangesAsync()
call
await dbContext.SaveChangesAsync().ConfigureAwait(false);
I am using
services.AddTransient<ProjectContext>();
in my startup.cs
. I tried AddScope
but it doesn't work.
Error:
System.ObjectDisposedException: '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.
Object name: 'ProjectContext'.'
Code:
private readonly Action<InjectedControllerArgs, ProjectDto, NavigationElements> _postAfterSave = async (injectedControllerArgs, dto, nav) => {
var memberClient = new MemberClient { MemberId = member.MemberId,
InvitationEmail = member.Email,
ClientId = dto.ClientId,
LastModifierId = member.MemberId };
await dbContext.MemberClient!.AddAsync(memberClient).ConfigureAwait(false);
await dbContext.SaveChangesAsync().ConfigureAwait(false);
var role = await dbContext.Role.Where(r => "client-admin" == r.RoleCode)
.FirstOrDefaultAsync()
.ConfigureAwait(false);
await dbContext.MemberClientRole!.AddAsync(new MemberClientRole
{ LastModifierId = member.MemberId,
MemberClientId = memberClient.MemberClientId,
RoleId = role.RoleId })
.ConfigureAwait(false);
await dbContext.SaveChangesAsync().ConfigureAwait(false); }
public async Task<ActionResult<ProjectDto>> PostInsertAsync(int customerId, int clientId, ProjectDto dto)
{
if (dto == null) throw new ArgumentNullException(nameof(dto));
dto.CustomerId = customerId;
dto.ClientId = clientId;
return await _pmBaseController.PostAsync(new NavigationElements(customerId, clientId, null), Topic, dto,
_returnOne, _postBeforeSave, _postAfterSave).ConfigureAwait(false);
}
public async Task<IActionResult> PutAsync(NavigationElements nav,
TopicName topic,
int id,
TDto dto,
Func<InjectedControllerArgs, NavigationElements, int, Task<T>> returnOne,
Func<TDto, int, TDto>? putBeforeSave = null,
Action<InjectedControllerArgs, TDto, NavigationElements>? putAfterSave = null
) ...
Upvotes: 1
Views: 455
Reputation: 1776
Your _postAfterSave
delegate is asynchronous but does not return a Task
which effectively means it is async void
so your _pmBaseController
is unable to await it which means execution will proceed before this Action
is done. That the first SaveChanges works is timing / coincidence.
Try changing the type from Action<InjectedControllerArgs, ProjectDto, NavigationElements>
to Func<InjectedControllerArgs, ProjectDto, NavigationElements, Task>
and make sure to await it everywhere.
Upvotes: 2