Сигнализация и сериализация массива объектов
Я новичок в SignalR и сделал простой тестовый Хак. Я хочу сериализовать массив объектов с типизированными объектами. По умолчанию SignalR настроил JSon.NET сериализатор, чтобы не предоставлять информацию о типе. И я обнаружил, что могу зарегистрировать пользовательский сериализатор в DependencyResolver с помощью:
var serializer =
new EventHubJsonSerializer(
new JsonSerializerSettings
{
PreserveReferencesHandling = PreserveReferencesHandling.Objects,
TypeNameHandling = TypeNameHandling.Objects
});
GlobalHost.DependencyResolver.Register(typeof(IJsonSerializer), () => serializer);
Однако, когда я получаю свой массив объектов, он не разрешает типы, вместо этого это JSonContainer. Могу ли я решить эту проблему каким-либо образом?
Событие, испускаемое из Концентратор:
public sealed class SignalREvent
{
public string Group { get; set; }
public string EventName { get; set; }
public string TypeFullName { get; set; }
public IList<object> EventArguments { get; set; }
}
И рецептор должен развернуть булево через приведение к динамическому:
public sealed class TestEventArgs : EventArgs
{
#region Public Properties
/// <summary>
/// Gets or sets a value indicating whether do not print.
/// </summary>
public bool DoNotPrint { get; set; }
/// <summary>
/// Gets or sets the event name.
/// </summary>
public string EventName { get; set; }
#endregion
}
this.subscription = this.client.On<SignalREvent>(
"PushEvent",
data =>
{
dynamic eventArg1 = data.EventArguments[0];
if (eventArg1.DoNotPrint.Value)
{
return;
}
});
То, что я сделал, - это постшарповый аспект для применения к событиям, чтобы позволить им распространяться через SignalR через мой EventHub. Например:
[ExternalizeEvent]
public event ASimpleDelegate SimpleEvent;
Это чертовски простой аспект, но было бы действительно хорошо иметь информацию о типе, когда в мире .net - другие клиенты, конечно, не выиграют от этого.
Обновить
Это выход для моего JSon.NET типы конфигурации распространяются в типе$, но кажется, что он не используется во время десерализации.
{
"$id": "11",
"$type": "<>f__AnonymousType0`3[[System.String, mscorlib],[System.String, mscorlib],[System.Object[], mscorlib]], SignalR",
"Hub": "Externalize.EventHub",
"Method": "PushEvent",
"Args": [
{
"$id": "12",
"$type": "DataDuctus.SignalR.Aspects.SignalREvent, DataDuctus.SignalR.Aspects",
"Group": "all",
"EventName": "SimpleEvent",
"TypeFullName": "TestConsole.TestEvents",
"EventArguments": [
{
"$id": "13",
"$type": "TestConsole.TestEventArgs, TestConsole",
"DoNotPrint": false,
"EventName": "second event (test)"
}
]
}
]
}
Ура!, Марио
1 ответ:
Клиент SignalR .NET не использует DependencyResolver от сервера и в настоящее время не имеет собственного контейнера IoC. Из-за этого, как вы заметили в своем вопросе, ваши пользовательские JsonSerializerSettings используются для сериализации на сервере, но не для десериализации на клиенте.
В следующем выпуске SignalR мы планируем добавить в клиент .NET DependencyResolver, который позволит вам предоставить свой собственный
Newtonsoft.Json.JsonSerializer
илиNewtonsoft.Json.JsonSerializerSettings
для использования во время десериализации. Там в настоящее время нет планов разрешить использование non-Json.NET (de)сериализатор в клиенте .NET.Если вам сейчас нужна эта функциональность, Вы могли бы клонировать https://github.com/SignalR/SignalR.git и модифицируйте Метод
private static T Convert<T>(JToken obj)
в SignalR.Клиент\Концентраторы\HubProxyExtensions.cs toreturn obj.ToObject<T>(yourJsonSerializer)
.