Мне нужны некоторые рекомендации от разработчиков SignalR, что лучший способ настройки сериализации параметров метода HUB.
Я начал переносить свой проект из дуплексного опроса WCF (Silverlight 5 - ASP.NET 4.5) в SignalR (1.1.2). Сообщение (контракт данных) является полиморфным на основе интерфейсов. (Как IMessage, MessageA: IMessage и т.д. - на самом деле иерархия интерфейсов реализована классами, но это не имеет большого значения для вопроса). (Я знаю, что полиморфные объекты не подходят для клиентов, но клиент будет обрабатывать его как JSON, а сопоставление с объектами выполняется только на стороне сервера или клиента, если это .NET/Silverlight)
На концентраторе я определил метод следующим образом:
public void SendMessage(IMessage data) { .. }
Я создал пользовательские JsonConverters и проверил, что сообщения могут быть сериализованы/десериализованы с использованием Json.NET. Затем я заменил JsonNetSerializer в DependencyResolver правильными настройками. Аналогично на стороне клиента Silverlight. Пока все хорошо.
Но когда я отправил сообщение от клиента на сервер (сообщение было правильно сериализовано в JSON - проверено в Fiddler), сервер ответил на ошибку, что параметр не может быть десериализован. С помощью отладчика я обнаружил ошибку в SignalR (класс JRawValue, ответственный за десериализацию параметра, создает внутренне собственный экземпляр JsonSerializer, игнорируя предоставленный). Кажется, это довольно легко исправить, заменив
var settings = new JsonSerializerSettings
{
MaxDepth = 20
};
var serializer = JsonSerializer.Create(settings);
return serializer.Deserialize(jsonReader, type);
с
var serializer = GlobalHost.DependencyResolver.Resolve<IJsonSerializer>();
return serializer.Parse(jsonReader, type);
но я также обнаружил, что интерфейс IJsonSerializer будет удален в будущей версии SignalR. Мне нужно, в основном, получить либо сырой поток JSON (или байтовый поток) из метода HUB, чтобы я мог десериализовать его самостоятельно, либо возможность настроить сериализатор, указав преобразователи и т.д.
В настоящее время я закончил с определением метода с типом параметра JObject:
public void SendMessage(JObject data)
за которым следует ручная десериализация данных с использованием
JObject.ToObject<IMessage>(JsonSerializer)
метод. Но я бы предпочел настроить сериализатор и иметь тип/интерфейс для метода хаба. Что такое "правильный путь" для создания следующего сигнала SignalR?
Мне также было полезно иметь возможность отправлять обратно сырые JSON клиентам из моего кода, т.е. чтобы объект снова не был снова сериализован сигналом. Как я мог достичь этого?