1

I’m currently working on a project involving an ASP.NET Core 8 application with SignalR for real-time notifications with SQL Server, an Angular 18 frontend, and SQL Server 2022 Express edition as the database.

I’m experiencing issues with SignalR not sending notifications to the clients after performing CRUD operations on the database.

Here’s a summary of my setup:

Program.cs:

using DocumentApp.Models;
using DocumentApp.Hubs;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext<AppDbContext>(options =>
    options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection")));
builder.Services.AddSignalR();
builder.Services.AddControllers();
builder.Services.AddCors(options =>
{
    options.AddPolicy("AllowAngularApp",
        builder => builder
            .WithOrigins("http://localhost:4200")
            .AllowAnyHeader()
            .AllowAnyMethod()
            .AllowCredentials());
});

var app = builder.Build();

app.UseCors("AllowAngularApp");
app.UseHttpsRedirection();
app.UseAuthorization();

app.MapControllers();
app.MapHub<NotificationHub>("/NotificationHub");

app.Run();

AppDbContext.cs:

using Microsoft.EntityFrameworkCore;

namespace DocumentApp.Models
{
    public class AppDbContext : DbContext
    {
        public DbSet<Document> Documents { get; set; }

        public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Document>().HasKey(d => d.DocumentId);
        }
    }

    public class Document
    {
        public int DocumentId { get; set; }
        public string DocumentCode { get; set; } = string.Empty;
    }
}

NotificationHub.cs:

using Microsoft.AspNetCore.SignalR;

namespace DocumentApp.Hubs
{
    public class NotificationHub : Hub
    {
        // This hub will be used to send notifications to clients
    }
}

DocumentsController.cs:

using DocumentApp.Models;
using DocumentApp.Hubs;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
using Microsoft.EntityFrameworkCore;

namespace DocumentApp.Controllers
{
    [ApiController]
    [Route("api/[controller]")]
    public class DocumentsController : ControllerBase
    {
        private readonly AppDbContext _context;
        private readonly IHubContext<NotificationHub> _hubContext;

        public DocumentsController(AppDbContext context, IHubContext<NotificationHub> hubContext)
        {
            _context = context;
            _hubContext = hubContext;
        }

        [HttpGet]
        public async Task<ActionResult<IEnumerable<Document>>> GetDocuments()
        {
            await _hubContext.Clients.All.SendAsync("ReceiveUpdate", "Documents retrieved!");
            return await _context.Documents.ToListAsync();
        }

        [HttpPost]
        public async Task<IActionResult> CreateDocument([FromBody] Document document)
        {
            _context.Documents.Add(document);
            await _context.SaveChangesAsync();
            await _hubContext.Clients.All.SendAsync("ReceiveUpdate", $"Document {document.DocumentCode} created!");
            return Ok(document);
        }

        [HttpPut("{id}")]
        public async Task<IActionResult> UpdateDocument(int id, [FromBody] Document document)
        {
            var existingDocument = await _context.Documents.FindAsync(id);
            if (existingDocument == null) return NotFound();

            existingDocument.DocumentCode = document.DocumentCode;
            await _context.SaveChangesAsync();
            await _hubContext.Clients.All.SendAsync("ReceiveUpdate", $"Document {document.DocumentCode} updated!");
            return Ok(existingDocument);
        }
    }
}

Angular 18 frontend:

SignalRService (signalr.service.ts):

import { Injectable } from '@angular/core';
import * as signalR from '@microsoft/signalr';

@Injectable({
  providedIn: 'root'
})
export class SignalRService {
  private hubConnection: signalR.HubConnection;

  constructor() {
    this.hubConnection = new signalR.HubConnectionBuilder()
      .withUrl('https://localhost:7203/NotificationHub')
      .configureLogging(signalR.LogLevel.Information)
      .build();

    this.hubConnection.start()
      .then(() => console.log('SignalR connection established'))
      .catch(err => console.error('Error establishing connection:', err));

    this.hubConnection.on('ReceiveUpdate', (message: string) => {
      console.log('Notification received:', message);
    });
  }
}

SQL Server - database configuration:

ALTER DATABASE DMS_DB_1_0_0
SET ENABLE_BROKER;
GO

SQL Server Agent: enabled the SQL Server Agent.

Problem

Despite performing CRUD operations (create, update, delete) through the API, the SignalR notifications are not being received in the Angular client. I've tried connecting directly to the /NotificationHub endpoint via Postman, which connects but doesn't receive any notifications.

Console error: when accessing https://localhost:7203/NotificationHub directly in the browser, I receive a "Connection ID required" error.

Steps taken to diagnose:

  1. Verified that the SignalR Hub is correctly mapped in Program.cs.
  2. Checked that the SignalR client in Angular is properly configured.
  3. Ensured that CORS is correctly set up to allow connections from the Angular app.
  4. Tried testing WebSocket connections with Postman, which connects but doesn't receive notifications.

Question

What steps should I take to resolve this issue? How can I ensure that SignalR notifications are properly sent and received by the Angular client? Are there any additional configurations or debugging techniques I should try?

Thank you in advance for your help!

1
  • I have tried your code, I am able to get the notification correctly here you can see: image. you could first make sure both the port running is correctly set up on client and backend. run the api and made test check if the operation is successful or not. and double confirm with your database. check the console logs for more information Commented Sep 9, 2024 at 8:17

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.