New to Telerik UI for ASP.NET CoreStart a free 30-day trial

SignalR Binding

SignalR allows you to add real-time functionality to your Grid. SignalR takes care of everything behind the scenes that makes real-time client-to-server and server-to-client communications possible. This is useful in collaborative scenarios where multiple parties are editing the Grid simultaneously or in apps that utilize push notifications.

You can use it with both the Telerik UI helpers for MVC and Core because they wrap the Kendo UI for jQuery Grid.

For a runnable example, refer to the demo on SignalR binding of the Grid component.

As of the ASP.NET Core R2 2018 release, the suite provides SignalR support for its components.

This article provides step-by-step instructions on using SignalR binding with the Grid.

SignalR Versions

Two versions of SignalR exist—ASP.NET Core SignalR and ASP.NET SignalR. It is important to note that ASP.NET Core SignalR is not compatible with clients or servers for ASP.NET SignalR. This means, for example, that you cannot connect a ASP.NET SignalR server to a client using ASP.NET Core SignalR client library.

The table below highlights the major differences between ASP.NET SignalR and ASP.NET Core SignalR:

ASP.NET SignalRASP.NET Core SignalR
Server NuGet packageMicrosoft.AspNet.SignalRNone. Included in the Microsoft.AspNetCore.App shared framework.
Client NuGet packagesMicrosoft.AspNet.SignalR.Client
Microsoft.AspNet.SignalR.JS
Microsoft.AspNetCore.SignalR.Client
JavaScript client npm packagesignalr@microsoft/signalr
Server app typeASP.NET (System.Web) or OWIN Self-HostASP.NET Core
Supported server platforms.NET Framework 4.5 or later.NET Core 3.0 or later

For further details, refer to the official Microsoft documentation.

The Telerik UI for ASP.NET Core Grid uses the ASP.NET Core SignalR service, and the example below demonstrates how to set up the Grid with this service. If you use ASP.NET SignalR, refer to Microsoft's documentation for complete details on configuring the server and client-side hubs and hub connections.

Setting Up the ASP.NET Core SignalR Service

To configure ASP.NET Core SignalR service, edit the Program.cs file and add SignalR to the services collection. Once done, ensure the hubs are mapped, as well.

Razor
    var builder = WebApplication.CreateBuilder(args);

    builder.Services.AddSignalR(opt => opt.EnableDetailedErrors = true).AddJsonProtocol(options => {
        options.PayloadSerializerOptions.PropertyNamingPolicy = null;
    });
    ...
    var app = builder.Build();
    ...
    app.MapHub<ProductHub>("/products");

    app.Run();

Configuring the Hub

SignalR uses hubs to communicate between clients and servers. A hub is a high-level pipeline that allows the client-server communication. The SignalR Hubs API enables you to call methods on connected clients from the server.

The example below demonstrates a sample Hub implementation:

Razor
    public class ProductHub(SampleEntitiesDataContext context) : Hub
    {
        public override Task OnConnectedAsync()
        {
            Groups.AddToGroupAsync(Context.ConnectionId, GetGroupName());
            return base.OnConnectedAsync();
        }

        public override Task OnDisconnectedAsync(Exception e)
        {
            Groups.RemoveFromGroupAsync(Context.ConnectionId, GetGroupName());
            return base.OnDisconnectedAsync(e);
        }

        public IEnumerable<ProductSignalR> Read()
        {
            var products = context.Products.Select(p => new ProductSignalR
            {
                ID = p.ProductID,
                ProductName = p.ProductName,
                UnitPrice = (double)p.UnitPrice.GetValueOrDefault(),
                UnitsInStock = p.UnitsInStock.GetValueOrDefault(),
                CreatedAt = DateTime.Now.AddMilliseconds(1),
                Category = new CategorySignalR
                {
                    CategoryID = p.Category.CategoryID,
                    CategoryName = p.Category.CategoryName
                }
            }).ToList();

            return products;
        }

        public ProductSignalR Create(ProductSignalR product)
        {
            product.ID = DateTime.Now.Ticks;
            product.CreatedAt = DateTime.Now;
            product.Category ??= new CategorySignalR { CategoryID = 1 };

            Clients.OthersInGroup(GetGroupName()).SendAsync("create", product);
            return product;
        }

        public ProductSignalR Update(ProductSignalR product)
        {
            Clients.OthersInGroup(GetGroupName()).SendAsync("update", product);
            return product;
        }

        public void Destroy(ProductSignalR product)
        {
            Clients.OthersInGroup(GetGroupName()).SendAsync("destroy", product);
        }

        public string GetGroupName()
        {
            return GetRemoteIpAddress();
        }

        public string GetRemoteIpAddress()
        {
            return Context.GetHttpContext()?.Connection.RemoteIpAddress?.ToString();
        }
    }

Including the Client-Side Library

Ensure the client-side library matches the server-side library version. Connecting an ASP.NET SignalR server to a client using ASP.NET Core SignalR client library and vice versa is not supported.

Configuring the ASP.NET Core SignalR Client-Side Hub

  1. Add a reference to the client-side SignalR library.
  2. Initialize a hub.
  3. Start the hub.

For complete details and API reference on the client-side SignalR library, refer to Microsoft's documentation.

JavaScript
    <script src="https://cdnjs.cloudflare.com/ajax/libs/microsoft-signalr/8.0.7/signalr.min.js" integrity="sha512-7SRCYIJtR6F8ocwW7UxW6wGKqbSyqREDbfCORCbGLatU0iugBLwyOXpzhkPyHIFdBO0K2VCu57fvP2Twgx1o2A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
    <script>
        var hubUrl = "path/to/hub";
        var hub = new signalR.HubConnectionBuilder()
            .withUrl(hubUrl,{
                skipNegotiation: true,
                transport: signalR.HttpTransportType.WebSockets
            })
            .build();

        var hubStart = hub.start()
            .then(function (e) {
                $("#notification").data("kendoNotification").success("SignalR Hub Started!");
            })
            .catch(function (err) {
                return console.error(err.toString());
            });
    </script>

Configuring the Grid's DataSource

The next steps describe how to set up the Transport configuration of the Grid's DataSource to connect to the SignalR Hub.

Instruct the DataSource to use SignalR protocol for transmitting and operating with data in real-time.

Razor
@(Html.Kendo().Grid<ProductViewModel>()
    .Name("grid")
    .Columns(columns =>
    {
        columns.Bound(p => p.ProductName).Width(150);
        columns.Bound(p => p.UnitsInStock).Width(120);
        columns.Bound(p => p.Category).ClientTemplate("#=Category.CategoryName#").Width(150);
        columns.Bound(p => p.Category.CategoryName).Filterable(false);
        columns.Command(command => { command.Edit(); command.Destroy(); }).Width(200);
    })
    .ToolBar(c =>
    {
        c.Create();
    })
    .Editable(editable => editable.Mode(GridEditMode.InLine))
    .Scrollable()
    .Sortable()
    .DataSource(dataSource => dataSource
        .SignalR()
        .Transport(tr => tr
            .Promise("hubStart")
            .Hub("hub")
            .Client(c => c
                .Read("read")
                .Create("create")
                .Update("update")
                .Destroy("destroy"))
            .Server(s => s
                .Read("read")
                .Create("create")
                .Update("update")
                .Destroy("destroy")))
        .Schema(schema => schema
            .Model(model =>
            {
                model.Id("ID");
                model.Field("ID", typeof(int)).Editable(false);
                model.Field("UnitsInStock", typeof(int));
                model.Field(m => m.Category).DefaultValue(new CategoryViewModel() { CategoryID = 1, CategoryName = "Beverages" });
            })
        )
    )
)

SignalR with Push Notifications

The following example demonstrates a sample implementation of a Grid that uses SignalR to show push notifications.

JavaScript
$(document).ready(function() {
    var hubUrl = "path/to/hub";
    var hub = new signalR.HubConnectionBuilder()
        .withUrl(hubUrl,{
            skipNegotiation: true,
            transport: signalR.HttpTransportType.WebSockets
        })
        .build();

    var hubStart = hub.start()
        .then(function (e) {
            $("#notification").data("kendoNotification").success("SignalR Hub Started!");
        })
        .catch(function (err) {
            return console.error(err.toString());
        });
});

function onPush(e) {
    var notification = $("#notification").data("kendoNotification");
    notification.success(e.type);
}

See Also