This is a migrated thread and some comments may be shown as answers.

FIX: Grid with SignalR Binding Not Working with Batch on DataSource

1 Answer 293 Views
Grid
This is a migrated thread and some comments may be shown as answers.
Keith
Top achievements
Rank 1
Keith asked on 26 Jun 2017, 02:21 PM

Just want to share this in case anyone else runs into it.  When a Kendo UI grid is bound to a SignalR datasource and Batch = true for that datasource, the server will begin responding with the following during create/update/destroy method calls:

{"I":"1","E":"There was an error invoking Hub method 'tranimporterrorshub.update'."}

 

This is because the automatically generated JSON is in an incorrect format to bind to your hub methods.  

Example hub method: 

public class ExampleHub : Hub
{
    public DataSourceResult Read(DataSourceRequest request)
    {
        // read operations here
    }
 
    public async Task Update(IEnumerable<ExampleViewModel> rows)
    {
        foreach (var row in rows)
        {
            // Update operations here
        }
    }
 
    public async Task Destroy(IEnumerable<ExampleViewModel> rows)
    {
        foreach (var row in rows)
        {
            // Delete operations here
        }
    }
}

 

When the JSON for create/update/destroy is generated, it is something like this:

data:{"H":"exampleshub","M":"update","A":[{"models":[{"Id":1,"Example":"Test"},{"Id":3,"Example":"Test2"}]}],"I":2}

 

If you look closely, the "A" property in the JSON starts with a "[", which indicates an array, even though there is NOT an array of models.  ASP.NET MVC SignalR does not support a call with the "data" being an array (must be an object or basic type) and the following exception is thrown:

Exception: Exception thrown: 'Newtonsoft.Json.JsonSerializationException' in Newtonsoft.Json.dll ("Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.IEnumerable`1[ExampleViewModel]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.
To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List<T>) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'models', line 1, position 10.").

 

I found a fix for this.  Simply add this function and wire it up to the parameterMap property for your DataSource:

function datasourceParameterMap(data, type) {
    if (type !== 'read' && data.models) {
        return data.models;
    } else {
        return data;
    }
}

 

Hope this helps someone else so that they don't have to figure it out the hard way.

1 Answer, 1 is accepted

Sort by
0
Keith
Top achievements
Rank 1
answered on 26 Jun 2017, 02:42 PM

Small clarification.  The fix is still correct, but the reason for the issue is not the square brace in the beginning of the data, it's the extra "models" property added.  This is what is output by default (same as original post):

data:{"H":"exampleshub","M":"update","A":[{"models":[{"Id":1,"Example":"Test"},{"Id":3,"Example":"Test2"}]}],"I":2}

 

This is what SignalR in MVC needs:

data:{"H":"exampleshub","M":"update","A":[[{"Id":1,"Example":"Test"},{"Id":3,"Example":"Test2"}]],"I":2}

 

Note the removal of the "models" property.

Tags
Grid
Asked by
Keith
Top achievements
Rank 1
Answers by
Keith
Top achievements
Rank 1
Share this question
or