Data from SignalR hub not visible in Grid

11 posts, 0 answers
  1. Michael
    Michael avatar
    59 posts
    Member since:
    Jan 2012

    Posted 21 Feb 2019 Link to this post

    Hi!

    I have a problem with SignalR and the Grid.

    I have a hub like this:

    01.public class ACTaskHub : Hub
    02.{
    03.    private IMemoryCache taskCache;
    04. 
    05.    public ACTaskHub(IMemoryCache cache)
    06.    {
    07.        taskCache = cache;
    08.    }
    09. 
    10.    public override Task OnConnectedAsync()
    11.    {
    12.        //Groups.AddToGroupAsync(Context.ConnectionId, GetGroupName());
    13.        return base.OnConnectedAsync();
    14.    }
    15. 
    16.    public override Task OnDisconnectedAsync(Exception exception)
    17.    {
    18.        //Groups.RemoveFromGroupAsync(Context.ConnectionId, GetGroupName());
    19.        return base.OnDisconnectedAsync(exception);
    20.    }
    21. 
    22.    public IEnumerable<TaskViewModel> Read()
    23.    {
    24.        var tasks = taskCache.Get("tasks") as IEnumerable<TaskViewModel>;
    25. 
    26.        if (tasks == null)
    27.        {
    28.            var products = AppData.TaskList.Select(t => new TaskViewModel
    29.            {
    30.                ID = t.ID,
    31.                Name = t.Name,
    32.                LastRunTime = t.LastRunTime,
    33.                Duration = t.Duration,
    34.                Schedule = t.Schedule,
    35.                Status = t.Status.ToString(),
    36.                Result = t.LastResult,
    37.                Exception = t.Exception?.Message,
    38.                CreatedAt = DateTime.Now.AddMilliseconds(1)
    39.            });
    40.             
    41.            tasks = products.ToList();
    42.            taskCache.Set("tasks", tasks, TimeSpan.FromMinutes(30));
    43.        }
    44. 
    45.        return tasks;
    46.    }
    47. 
    48.    public TaskViewModel Create(TaskViewModel task)
    49.    {
    50.        //task.ID = Guid.NewGuid();
    51.        //product.CreatedAt = DateTime.Now;
    52.        //product.Category = product.Category ?? new CategorySignalR() { CategoryID = 1 };
    53. 
    54.        //Clients.OthersInGroup(GetGroupName()).SendAsync("create", task);
    55.        Clients.Others.SendAsync("create", task);
    56. 
    57.        return task;
    58.    }
    59. 
    60.    public void Update(TaskViewModel task)
    61.    {
    62.        //Clients.OthersInGroup(GetGroupName()).SendAsync("update", task);
    63.        Clients.Others.SendAsync("update", task);
    64.    }
    65. 
    66.    public void Destroy(TaskViewModel task)
    67.    {
    68.        //Clients.OthersInGroup(GetGroupName()).SendAsync("destroy", task);
    69.        Clients.Others.SendAsync("destroy", task);
    70.    }
    71. 
    72.    //public string GetGroupName()
    73.    //{
    74.    //    return GetRemoteIpAddress();
    75.    //}
    76. 
    77.    //public string GetRemoteIpAddress()
    78.    //{
    79.    //    return Context.GetHttpContext()?.Connection.RemoteIpAddress.ToString();
    80.    //}
    81.}

     

    And i use Kendo Grid with SignalR datasource to show the hub data like this:

    @(Html.Kendo().Grid<TaskViewModel>()
        .Name("TaskList")
        .Columns(columns =>
        {
            columns.Bound(t => t.Name).Width(140);
            columns.Bound(t => t.LastRunTime).Format("{0:yyyy-MM-dd hh:mm:ss}").Width(150);
            columns.Bound(t => t.Duration).HtmlAttributes(new { style = "text-align:right" }).Width(130);
            columns.Bound(t => t.Schedule).Width(100);
            columns.Bound(t => t.Status).Width(80);
            columns.Bound(t => t.Result).Filterable(false).Width(250);
            columns.Bound(t => t.Exception).Filterable(false).Width(150);
        })
        .Sortable()
        .Scrollable()
        .Filterable()
        .Resizable(resize => resize.Columns(true))
        .HtmlAttributes(new { style = "maxheight:530px;" })
        .DataSource(dataSource => dataSource
            .SignalR()
            .AutoSync(true)
            .Events(events => events.Push("onPush"))
            .Events(events => events.Error("onError"))
            .Sort(s => s.Add("CreatedAt").Descending())
            .Transport(tr => tr
                .Promise("hubStart")
                .Hub("hub")
                .Client(c => c
                    .Read("read")
                    .Create("create")
                    .Destroy("destroy")
                    .Update("update"))
                .Server(s => s
                    .Read("read")
                    .Create("create")
                    .Destroy("destroy")
                    .Update("update")))
            .Schema(schema => schema
                .Model(model =>
                {
                    model.Id("ID");
                    model.Field("ID", typeof(string)).Editable(false);
                    model.Field("CreatedAt", typeof(DateTime)).Editable(false);
                    model.Field("Name", typeof(string)).Editable(false);
                    model.Field("LastRunTime", typeof(DateTime)).Editable(false);
                    model.Field("Duration", typeof(TimeSpan)).Editable(false);
                    model.Field("Schedule", typeof(string)).Editable(false);
                    model.Field("Status", typeof(string)).Editable(false);
                    model.Field("Result", typeof(string)).Editable(false);
                    model.Field("Exception", typeof(string)).Editable(false);
                })
            )
        )
    )

     

    The hub is connected and the data are loaded, but not visible in the grid. I can see the like of my task in the grid because of mouse hovering but the fields are empty. (see screenshot1.png)

     

    The secound problem i have is, that when the data is updated from server the client want to invoke "create" method. Why is the client doing this?

    I get this error message: (see screenshot2.png)

     

    And why is the ASP.NET Core Grid SignalR demo not working: https://demos.telerik.com/aspnet-core/grid/signalr

     

     

     

     

  2. Michael
    Michael avatar
    59 posts
    Member since:
    Jan 2012

    Posted 21 Feb 2019 Link to this post

    I think I found out something that could explain the first error (data will not be shown):
    camelCase vs. PascalCase

    When I look at the JSON data from the WebSocket Monitor, they are transferred to camelCase. The model at the grid is specified in PascalCase.

    {"type":1,"target":"updateTask","arguments":[{"id":"d7c5c44f-03fa-401f-8b12-4f0ab3890b64","createdAt":"2019-02-21T15:06:27.8914385+01:00","name":"Hello World! Task","lastRunTime":"2019-02-21T15:03:26.5114048+01:00","duration":"00:00:06.3288123","schedule":"*/3 * * * *","status":"Running","result":"Hello World and hallo Mike!"}]}

    It may then have something to do with the second error as a result.

    Does Kendo Grid use camelCase or PascalCase?
  3. Michael
    Michael avatar
    59 posts
    Member since:
    Jan 2012

    Posted 22 Feb 2019 Link to this post

    Solution found: all the problems/failure were based on camelCase/PascalCase!

    Check your ConfigureServices method in Startup.cs for the following:

    01.services.AddMvc()
    02.        .SetCompatibilityVersion(CompatibilityVersion.Version_2_1)
    03.        .AddJsonOptions(o =>
    04.        {
    05.            o.SerializerSettings.ContractResolver = new DefaultContractResolver();
    06.            o.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
    07.        });
    08. 
    09.services.AddSignalR(hubOptions => hubOptions.EnableDetailedErrors = true)
    10.        .AddJsonProtocol(jsonOptions =>
    11.        {
    12.            jsonOptions.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver();
    13.            jsonOptions.PayloadSerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
    14.        });

     

    And check if you are using

    [JsonProperty("name")]

    in your models because this feature makes your Pascal Case attitude back to CamelCase.

    That was my mistake!

  4. Abdullah
    Abdullah avatar
    1 posts
    Member since:
    Nov 2018

    Posted 24 Apr 2019 in reply to Michael Link to this post

    thank you. changing the services with :

    services.AddSignalR(hubOptions => hubOptions.EnableDetailedErrors = true)
    .AddJsonProtocol(jsonOptions =>
    {
    jsonOptions.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver();
    jsonOptions.PayloadSerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
    });

    worked like hell..
  5. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    1082 posts

    Posted 29 Apr 2019 Link to this post

    Hi, Michael,

    The default serialization was changed by Microsoft in 2016 thus making it necessary to specify the the settings:

    https://github.com/aspnet/Announcements/issues/194

    We included this in our getting started article, step 5:

    https://docs.telerik.com/aspnet-core/getting-started/getting-started

    The serialization for SignalR should be part of the SignalR settings. Here is the link to the online project service startup file:

    https://github.com/telerik/kendo-ui-demos-service/blob/master/signalr-hubs/signalr-for-aspnet-core/Startup.cs#L40

    public void ConfigureServices(IServiceCollection services)
     {
          /* otherr services */
        services.AddSignalR()
            .AddJsonProtocol(x =>
                x.PayloadSerializerSettings.ContractResolver = new DefaultContractResolver());
    }

    Finally, you mentioned that the official SignalR ASP.NET Core demo does not work. Could you let us know what specifically  is not working so we can investigate?

    Kind Regards,
    Alex Hajigeorgieva
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  6. Michael
    Michael avatar
    59 posts
    Member since:
    Jan 2012

    Posted 29 Apr 2019 in reply to Alex Hajigeorgieva Link to this post

    Hi Alex,

    thx for the reply!

    I have checked the demo again, and now its working fine! (In those days, no data was loaded and displayed!)

  7. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    1082 posts

    Posted 02 May 2019 Link to this post

    Hello,Michael,

    Maybe it was a brief disruption on the server where the service is.

    It is great that it works fine now, thank you for getting in touch about it.

    Kind Regards,
    Alex Hajigeorgieva
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  8. Don
    Don avatar
    11 posts
    Member since:
    Apr 2018

    Posted 23 Oct 2019 Link to this post

    I just want to add to the answers... For applications using ASP.NET Core 3.0 framework, the codes to use is:

            public void ConfigureServices(IServiceCollection services)
            {
                // ** Other services such as AddMvc, AddNewtonsoftJson, AddKendo go here first **

                services.AddSignalR()
                    .AddJsonProtocol(options =>
                    {
                         options.PayloadSerializerOptions.PropertyNamingPolicy = null;
                    });

            }

  9. Alex Hajigeorgieva
    Admin
    Alex Hajigeorgieva avatar
    1082 posts

    Posted 24 Oct 2019 Link to this post

    Hi, Don,

    Thank you very much for updating the thread with your solution.

    Kind Regards,
    Alex Hajigeorgieva
    Progress Telerik

    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
  10. Dayanand
    Dayanand avatar
    1 posts
    Member since:
    Feb 2020

    Posted 25 Feb 2020 Link to this post

    What is AppData while creating SignalR hub in above example.  I am getting

     

      var products = AppData.TaskList.Select(t => new TaskViewModel
    29.            {
    30.                ID = t.ID,
    31.                Name = t.Name,
    32.                LastRunTime = t.LastRunTime,
    33.                Duration = t.Duration,
    34.                Schedule = t.Schedule,
    35.                Status = t.Status.ToString(),
    36.                Result = t.LastResult,
    37.                Exception = t.Exception?.Message,
    38.                CreatedAt = DateTime.Now.AddMilliseconds(1)
    39.            });

  11. Michael
    Michael avatar
    59 posts
    Member since:
    Jan 2012

    Posted 27 Feb 2020 in reply to Dayanand Link to this post

    AppData is a static DTO

    public static class AppData
    {
        static AppData()
        {
            TaskList = new List<Logic.OceanTask>();
        }
     
        //public static IServiceProvider Instance { get; set; }
        public static List<Logic.OceanTask> TaskList { get; private set; }
        public static string AppPath { get; set; }
        public static string WWWRootPath { get; set; }
    }
Back to Top