My Blazor Form works and does valid submission,but when I submit the form multiple times in a very small time interval, it gives different types of exceptions, like:
Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111] Unhandled exception in circuit '2e3Co_1JEKkjPKZ2_SWboRbCQARz01rKj3WwE5d61x4'. System.InvalidOperationException: A second operation was started on this context instance before a previous operation completed. This is usually caused by different threads concurrently using the same instance of DbContext.And also a warning:
Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100] Unhandled exception rendering component: Cannot access a disposed context instance. A common cause of this error is disposing a context instance 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 instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.And another fail:
Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111] Unhandled exception in circuit '2e3Co_1JEKkjPKZ2_SWboRbCQARz01rKj3WwE5d61x4'. System.ObjectDisposedException: Cannot access a disposed context instance. A common cause of this error is disposing a context instance 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 instance, or wrapping it 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: 'TimeTableContext'. at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed() at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies() at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken) at TimeTableApplication.DL.CourseDL.AddAsync(Course course)HOWEVER, If I wait for 1 second and it the form is successfully submitted, then no matter how many times I try to submit the form even multiple times it never causes exception.It is only one time thing after the application is started.I am not able to find the root cause, and error messages are not helping.
My Code Of Blazor Form which is a child component is:
@rendermode InteractiveServer<h3 class="text-center">Add Course</h3><EditForm Model="@Course" OnValidSubmit=" HandleValidSubmitAsync" FormName="AddCourse"><ObjectGraphDataAnnotationsValidator /><ValidationSummary /><div class="form-group row mb-3"><label for="coursename" class="col-sm-2 col-form-label"> Course Name</label><div class="col-sm-10 "><InputText id="coursename" class="form-control form-control-sm" placeholder="Course Name" @bind-Value="Course.Name" /><ValidationMessage For="@(() => Course.Name)" /></div></div> <div class="form-group row mb-3"><label for="semester" class="col-sm-2 col-form-label"> Semester</label><div class="col-sm-10"><InputSelect @bind-Value="semesterName" class="form-control form-control-sm"> @foreach (var name in SemesterNames) {<option value="@name">@name</option> }</InputSelect><ValidationMessage For="@(() => Course.Semester)" /></div></div><div style="display:flex;align-items:center;justify-content:center"> <MudButton ButtonType="ButtonType.Submit" Variant="Variant.Filled" Color="Color.Primary" >Register</MudButton></div></EditForm>The code of this component is:
using Microsoft.AspNetCore.Components;using MudBlazor;using TimeTableApplication.DL;using TimeTableApplication.Models.DB_Models;using static TimeTableApplication.Fixed.Enums;namespace TimeTableApplication.Components.Courses{ public partial class AddCourse { private Course Course { get; set; } = new() { Name = "", Semester = 1, DepartmentName = DepartmentName.ComputerScience.ToString() }; private List<string> SemesterNames { get; set; } = ["Semester 1", "Semester 3", "Semester 5", "Semester 7"]; private string semesterName = "Semester 1"; [Inject] private CourseDL? CourseDL { get; set; } [Inject] NavigationManager? NavigationManager { get; set; } [Inject] ISnackbar Snackbar { get; set; } private async Task HandleValidSubmitAsync() { Course.Semester = int.Parse(semesterName.Split('')[1]); if (await CourseDL.AddAsync(Course)) { Snackbar.Add($"Course: {Course.Name} Successfully added!", Severity.Info); await Task.Delay(500); NavigationManager.NavigateTo("/courses", true); Course = new() { Name = "", Semester = 1, DepartmentName = DepartmentName.ComputerScience.ToString() }; } else { Snackbar.Add($"Failure, Course: {Course.Name} Already Exists!", Severity.Error); } } }}My Data Layer of EF Core is:
using Microsoft.EntityFrameworkCore;using TimeTableApplication.Models.DB_Models;namespace TimeTableApplication.DL{ public class CourseDL { private readonly TimeTableContext context; public CourseDL(TimeTableContext context) { this.context = context; } public async Task<bool> AddAsync(Course course) { if (!await IsPresentAsync(course)) { await context.Courses.AddAsync(course); await context.SaveChangesAsync(); // Ensure changes are saved return true; } return false; } public async Task<bool> UpdateAsync(Course course) { if (await IsPresentAsync(course)) { context.Courses.Update(course); await context.SaveChangesAsync(); // Ensure changes are saved return true; } return false; } public async Task<bool> RemoveAsync(Course course) { if (await IsPresentAsync(course)) { context.Courses.Remove(course); await context.SaveChangesAsync(); // Ensure changes are saved return true; } return false; } public async Task<bool> IsPresentAsync(Course course) { return await context.Courses .AnyAsync(a => a.Name == course.Name && a.Semester == course.Semester && a.DepartmentName == course.DepartmentName); } public async Task<List<Course>> GetAllBySemesterAsync(string deptName) { return await context .Courses .Where(a => a.DepartmentName == deptName) .OrderBy(a => a.Semester) .ThenBy(a => a.Name) .ToListAsync(); } }}My services are registered as:
builder.Services.AddScoped<CourseDL, CourseDL>();builder.Services.AddDbContext<TimeTableContext>(options => options.UseSqlServer(builder.Configuration.GetConnectionString("Default")), ServiceLifetime.Transient);Note: I have already tried different lifespans of dependency injection for my DBContext, but it is not working