Y
Y
YungSherman2018-04-24 15:41:23
ASP.NET
YungSherman, 2018-04-24 15:41:23

Why is writing to the database not working?

I am developing a web application using ASP.NET-Core and EntityFrameworkCore. I decided to implement a chat in it using WebSocket. I took the article from this link as a basis. It seems to work well, I want to add a message record to the database, but there is a problem.
I have a message model class like this:

public class GroupChatMessage
{
    public int ID { get; set; }
    public int CompanyID { get; set; }
    public int UserID { get; set; }
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true)]
    public DateTime CreationDate { get; set; }
    public string Text { get; set; }

    public Company Company { get; set; }
    [NotMapped]
    public UserPlusWorkerModel UserPlusWorker { get; set; }
    //public User User { get; set; }
}

There is a database access context:
public class EnterChatContext : DbContext
{
    public EnterChatContext(DbContextOptions<EnterChatContext> options) : base(options)
    {

    }

    public DbSet<User> Users { get; set; }
    public DbSet<TopicMessage> TopicMessages { get; set; }
    public DbSet<Topic> Topics { get; set; }
    public DbSet<Note> Notes { get; set; }
    public DbSet<GroupChatMessage> GroupChatMessages { get; set; }
    public DbSet<File> Files { get; set; }
    public DbSet<Company> Companies { get; set; }
    public DbSet<Worker> Workers { get; set; }
    public DbSet<Department> Departments { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {

        modelBuilder.Entity<User>().ToTable("User");
        modelBuilder.Entity<TopicMessage>().ToTable("TopicMessage");
        modelBuilder.Entity<Topic>().ToTable("Topic");
        modelBuilder.Entity<Note>().ToTable("Note");
        modelBuilder.Entity<GroupChatMessage>().ToTable("GroupChatMessage");
        modelBuilder.Entity<File>().ToTable("File");
        modelBuilder.Entity<Company>().ToTable("Company");
        modelBuilder.Entity<Worker>().ToTable("Worker");
        modelBuilder.Entity<Department>().ToTable("Departments");


        base.OnModelCreating(modelBuilder);
    }
}

Here is the method of the ChatWebSocketMiddleWare class, in which the message is received and processed:
private static Task SendStringAsync(WebSocket socket, string data, CancellationToken ct = default(CancellationToken))
    {
        var buffer = Encoding.UTF8.GetBytes(data);
        var segment = new ArraySegment<byte>(buffer);
        var optionsBuilder = new DbContextOptionsBuilder<EnterChatContext>();
        //optionsBuilder.UseSqlite("Server=(localdb)\\mssqllocaldb;Database=EnterChatWebDB;");
        using (var context = new EnterChatContext(optionsBuilder.Options))
        {
            GroupChatMessage message = new GroupChatMessage
            {
                //просто тестовые данные
                UserID = 1,
                CompanyID = 1,
                Text = data,
                CreationDate = DateTime.Now
            };
            context.GroupChatMessages.AddAsync(message);
            context.SaveChangesAsync();
        }
        return socket.SendAsync(segment, WebSocketMessageType.Text, true, ct);
    }

The problem is that the message is not being written to the database. In the controller classes, I use the same context class and everything works fine. I can't figure out what I might be missing.

Answer the question

In order to leave comments, you need to log in

3 answer(s)
Y
YungSherman, 2018-04-24
@YungSherman

I decided to add to the database in another method of the ChatWebSocketMiddleWare class, namely Invoke(). In it, HttpContext was passed in the parameters, and I also decided to add a parameter for the access context to the database. Everything started working fine:

public async Task Invoke(HttpContext context, EnterChatContext chatContext)
        {
            if (!context.WebSockets.IsWebSocketRequest)
            {
                await _next.Invoke(context);
                return;
            }

            CancellationToken ct = context.RequestAborted;
            WebSocket currentSocket = await context.WebSockets.AcceptWebSocketAsync();
            var socketId = Guid.NewGuid().ToString();

            _sockets.TryAdd(socketId, currentSocket);

            while (true)
            {
                if (ct.IsCancellationRequested)
                {
                    break;
                }

                var response = await ReceiveStringAsync(currentSocket, ct);
                if (string.IsNullOrEmpty(response))
                {
                    if (currentSocket.State != WebSocketState.Open)
                    {
                        break;
                    }

                    continue;
                }
                int user_id = Int32.Parse(context.User.FindFirst(ClaimTypes.NameIdentifier).Value);
                int comp_id = Int32.Parse(context.User.FindFirst("CompanyID").Value);
                GroupChatMessage message = new GroupChatMessage
               {
                        UserID = user_id,
                        CompanyID = comp_id,
                        Text = response,
                        CreationDate = DateTime.Now
                };
                await chatContext.GroupChatMessages.AddAsync(message);
                await chatContext.SaveChangesAsync();
                

                foreach (var socket in _sockets)
                {
                    if (socket.Value.State != WebSocketState.Open)
                    {
                        continue;
                    }

                    await SendStringAsync(socket.Value, response, ct);
                }
            }
            WebSocket dummy;
            _sockets.TryRemove(socketId, out dummy);

            await currentSocket.CloseAsync(WebSocketCloseStatus.NormalClosure, "Closing", ct);
            currentSocket.Dispose();
        }

F
FreeBa, 2018-04-24
@FreeBa

And why are you using asynchronous methods in synchronous code? This is somewhat counterintuitive, and given the lazy nature of such methods, can lead to ambiguous behavior - use async/await.

B
basrach, 2018-04-24
@basrach

you missed the word await before context.SaveChangesAsync();

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question