0

I have this form and when I try to submit the form, my DB gets a register with null fields, every field that supposed to fill in the form, I sent null, but the fields I've preset the value reaches the database.

This is my edit form:

<EditForm Model="@Registros" OnValidSubmit="@HandleValidSubmit" FormName="RegistrosForm">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <table class="table">
        <tr>
            <th><strong>No.</strong></th>
            <th><strong>Cliente</strong></th>
            <th><strong>Asunto</strong></th>
            <th><strong>Resumen del reporte</strong></th>
            <th><strong>Describa con más detalle el registro</strong></th>
            <th><strong>Fecha</strong></th>
            <th><strong>Estado</strong></th>
        </tr>
        <tr>
            <td>@ContadorId</td>
            <td>
                <InputSelect id="Cliente" class="form-control" @bind-Value="Registros.Cliente">
                    <option value="">Seleccione una opcion</option>
                    @foreach (var cliente in Clientes)
                    {
                        <option value="@cliente.Nombre">@cliente.Nombre</option>
                    }
                </InputSelect>
            </td>
            <td>
                <InputSelect id="Asunto" class="form-control" @bind-Value="Registros.Asunto">
                    <option value="">Seleccione una opcion</option>
                    @foreach (var asunto in Asuntos)
                    {
                        <option value="@asunto.Asuntos">@asunto.Asuntos</option>
                    }
                </InputSelect>
            </td>
            <td>
                <InputText id="Resumen" class="form-control" @bind-Value="Registros.DescCorta" />
            </td>
            <td>
                <InputText id="Descripcion" class="form-control" @bind-Value="Registros.Descripcion" />
            </td>
            <td>
                <span>@Registros.Fecha.ToString("dd/MM/yyyy")</span>
            </td>
            <td>
                Nuevo
            </td>
        </tr>
    </table>

    <button type="submit" class="btn btn-primary">ACEPTAR</button>
</EditForm>

And here's my C# code:

@code {
    private Registros Registros = new Registros
        {
            Nombre = string.Empty,
            Asunto = string.Empty,
            Cliente = string.Empty,
            DescCorta = string.Empty,
            Descripcion = string.Empty
        };

    private string? UserName;
    private string? UserLastName;

    private int ContadorId;

    private List<Clientes> Clientes = new List<Clientes>();
    private List<Asunto> Asuntos = new List<Asunto>();
    private List<Registros> UserRegistros = new List<Registros>();

    private ApplicationUser? currentUser;

    protected override async Task OnInitializedAsync()
    {
        try
        {
            var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
            var userPrincipal = authState.User;

            if (userPrincipal.Identity?.IsAuthenticated == true)
            {
                currentUser = await usermanager.GetUserAsync(userPrincipal);
                UserName = currentUser?.FirstName ?? userPrincipal.Identity.Name;
                UserLastName = currentUser?.LastName;
            }

            Registros.Fecha = DateTime.Now;
            ContadorId = IdDisplayContador();

            // Crear instancias separadas del DbContext de forma correcta
            await using var dbContext = DbContextFactory.CreateDbContext();

            Clientes = await dbContext.Clientes.ToListAsync();
            Asuntos = await dbContext.Asuntos.ToListAsync();

            UserRegistros = await dbContext.Registros
                .Where(r => r.Nombre == UserName + " " + UserLastName)
                .ToListAsync();
        }
        catch (Exception ex)
        {
            // Handle exceptions (e.g., log the error)
            Console.Error.WriteLine($"Error during initialization: {ex.Message}");
        }
    }

    private async Task LoadClientesAsync()
    {
        try
        {
            await using var dbContext = DbContextFactory.CreateDbContext();
            Clientes = await dbContext.Clientes.ToListAsync();
        }
        catch (Exception ex)
        {
            // Handle exceptions (e.g., log the error)
            Console.Error.WriteLine($"Error loading clients: {ex.Message}");
        }
    }

    private async Task LoadAsuntosAsync()
    {
        try
        {
            await using var dbContext = DbContextFactory.CreateDbContext();
            Asuntos = await dbContext.Asuntos.ToListAsync();
        }
        catch (Exception ex)
        {
            // Handle exceptions (e.g., log the error)
            Console.Error.WriteLine($"Error loading issues: {ex.Message}");
        }
    }

    private async Task HandleValidSubmit()
    {
        try
        {
            // Asegurarse de que UserName y UserLastName estén asignados
            if (string.IsNullOrEmpty(UserName) || string.IsNullOrEmpty(UserLastName))
            {
                var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
                var userPrincipal = authState.User;

                if (userPrincipal.Identity?.IsAuthenticated == true)
                {
                    currentUser = await usermanager.GetUserAsync(userPrincipal);
                    UserName = currentUser?.FirstName ?? userPrincipal.Identity.Name;
                    UserLastName = currentUser?.LastName;
                }
            }

            //debe insertar los datos que se llenaron en el formulario
            Registros.Nombre = UserName + " " + UserLastName;
            Registros.Estado = "Nuevo";

            await using (var dbContext = DbContextFactory.CreateDbContext())
            {
                dbContext.Registros.Add(Registros);
                await dbContext.SaveChangesAsync();
            }

            // Usar un nuevo contexto para recargar los registros
            await using (var dbContext = DbContextFactory.CreateDbContext())
            {
                UserRegistros = await dbContext.Registros
                    .Where(r => r.Nombre == $"{UserName} {UserLastName}")
                    .ToListAsync();
            }
        }
        catch (Exception ex)
        {
            Console.Error.WriteLine($"Error saving record: {ex.Message}");
        }
    }

    private int IdDisplayContador()
    {
        return ++ContadorId;
    }
}

The console shows this exception:

fail: Microsoft.EntityFrameworkCore.Query[10100]

An exception occurred while iterating over the results of a query for context type 'BlazorApp1.Data.ApplicationDbContext'.

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. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/? linkid=2097913.

at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection()
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
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. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.

at Microsoft.EntityFrameworkCore.Infrastructure.Internal.ConcurrencyDetector.EnterCriticalSection()
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()

Error during initialization: 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. For more information on how to avoid threading issues with DbContext, see https://go.microsoft.com/fwlink/?linkid=2097913.

I've tried to make different instances but I'm new to Blazor and I don't know if I'm doing right. I already checked the table and the model and everything looks fine.

6
  • How/where do you call LoadAsuntosAsync() and what is your rendermode? Itr looks like Static but it's good to be clear. Commented Mar 2 at 15:36
  • Which line throws the exception? Commented Mar 2 at 18:25
  • I would like to mention as well, that the error might originate from somewhere else in your app. You already create a new instance of the DbContext before every data operation, which should solve your issue, but apparently its not. Thats why @GertArnold probably asks where the exception is thrown. Maybe its not actually thrown in the component you have shown here. Commented Mar 2 at 19:16
  • You are using Entity with DbContext( see learn.microsoft.com/en-us/ef/core/dbcontext-configuration) The error is being cause by a second DbContext being created before the first one is disposed. Either make sure all the paths have a dispose, or add a lock (learn.microsoft.com/en-us/dotnet/api/… the code to prevent two threads creating a DbContext simultaneously. Commented Mar 2 at 21:48
  • Also add your DbContextFactory implementation. One odd detail you are awaiting the IDbContextFactory.CreateDbContext() which is normally a synchronous method. This error can occur if two threads access the same DbContext instance, including if 2 or more async operations are called without awaiting. Nothing stands out as a red flag in your example, but that hinges on that your factory is actually passing back a new DbContext instance on CreateDbContext(). Commented Mar 3 at 3:46

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.