Как правильно перейти с WCF DatacontractSerializer на Protobuf-net?

У нас есть огромное приложение с множеством классов. В настоящее время мы переносим это приложение .net на IPad с помощью Monotouch. У нас есть некоторые проблемы с DataContractSerializer, и мы хотели бы использовать сериализатор protobuf-net Марка Гравелла.

Связью между клиентом и сервером управляет служба WCF.

Служба WCF состоит из одного интерфейса, доступного для клиента и сервера, и одной реализации этого интерфейса на сервере.

Интерфейс выглядит так:

[ServiceContract]
public interface IMyService
{
    [OperationContract]
    SomeObject MyFunction(SomeObject myObject);
}

Реализация на стороне сервера выглядит так:

[ServiceBehavior(...)]
public class MyService
{
    public SomeObject MyFunction(SomeObject myObject)
    {
    }
}

Наши классы выглядят так:

[DataContract]
public class MyClass
{
    [DataMember]
    public int SomeProp {get; set;}

    [OnSerialized]
    public void OnSerialized(StreamingContext context)
    {
    }
}

Итак, вот мои вопросы:

  • Какие изменения следует внести в мои классы, интерфейс wcf и реализацию wcf.

  • Как мне заменить стандартный WCF DataContractSerializer на Protobuf Serializer.

Обратите внимание, что в режиме monotouch у меня есть доступ только к пространствам имен Protobuf и Protobuf.Meta.

[EDIT] Я нашел способ поменять местами среду выполнения сериализатора: Custom WCF DataContractSerializer

В приведенном выше решении используется DataContractSerializerOperationBehavior. Обеспечивает ли Protobuf-net такое поведение?


person Jean-Philippe Leclerc    schedule 05.08.2011    source источник
comment
Во-вторых, что сказал Марк: не думайте, что только потому, что вы можете заменить сериализатор на MS .NET, вы можете сделать это в Mono, не говоря уже о MonoTouch. Стек WCF Mono незрелый, и MT реализует только подмножество из этого ...   -  person TheNextman    schedule 05.08.2011


Ответы (1)


Честно говоря, я не знаком с опциями WCF, доступными вам в monmotouch; например, они сильно различаются между обычным .NET и Silvelight - и я не вижу причин предполагать, что monotouch может менять местами сериализатор во время выполнения (что делает "полный" .NET, по крайней мере, в версии для MS). Это затрудняет выполнение перехода незаметно, поскольку мы не можем бороться с управлением от DataContractSerializer.

Таким образом, ИМО, самый простой вариант - захватить контроль над данными вручную и отправить необработанные byte[] - в идеале с включенным кодированием MTOM, если одно касание может это сделать. Как говорится, когда у вас есть ваш byte[], мир становится вашим моллюском.

Повторные изменения ваших типов ... ну, MyFunction() - это странность, поскольку он не передает никаких данных, поэтому я не уверен, что вы хотите, чтобы я предложил по этому поводу. С MyClass все, что ему нужно, - это уникальный номер (уникальный внутри типа, а не глобально) для каждого члена, т.е.

[DataContract]
public class MyClass
{
    [DataMember(Order=1)] // <==== this provides the 1 as the key
    public int SomeProp {get; set;}

    // see below re callback
}

У вас также есть обратный вызов сериализации; они полностью поддерживаются, но ожидается, что он найдет знакомый шаблон - StreamContext не тот, о котором я знаю (хотя он должен работать с StreamingContext и некоторыми другими).

Наконец, обратите внимание, что по умолчанию protobuf-net выполняет конструктор, который отличается от DataContractSerializer. Если хотите, вы можете подавить это с помощью:

[DataContract(SkipConstructor=true)]
public class MyClass {...}

Если я пропустил здесь намерение, дайте мне знать.

Обратите внимание, что есть также способы выполнить всю настройку без изменения / добавления каких-либо атрибутов, если хотите.

person Marc Gravell    schedule 05.08.2011
comment
Спасибо за ответ Марк. В своем интерфейсе (MyFunction) я хотел показать, что у меня есть атрибут ServiceContract и OperationContract. Я бы хотел знать, остались ли эти атрибуты прежними? И я допустил ошибку при вводе своего примера, это не StreamContext, а StreamingContext. Отредактирую свой пост. - person Jean-Philippe Leclerc; 05.08.2011
comment
И как мне выполнить настройку без изменения каких-либо атрибутов? - person Jean-Philippe Leclerc; 05.08.2011
comment
@Jean - по поводу последнего вопроса; v2 имеет RuntimeTypeModel, который позволяет все настраивать. Повторите первое - без замены основного сериализатора (что можно сделать в полной версии MS .NET). Поэтому я предлагаю использовать byte[] в качестве основного объекта API, чтобы мы могли контролировать сериализацию вне this. Согласен, не так удобно, как .NET. Конечно, в этот момент вы можете задаться вопросом, что WCF добавляет для вас ... может быть, простой сокет или HTTP POST проще. - person Marc Gravell; 06.08.2011
comment
@MarcGravell есть ли способ автоматически заполнить заказ из DataContract, который будет использоваться в Protobuf.NET в качестве имени в алфавитном порядке? Например: [DataMember (Name = a) будет Order = 1. - person Iúri dos Anjos; 29.06.2018
comment
@ IúridosAnjos, чтобы уточнить: есть ли Order = x в существующих атрибутах элементов данных? и уникальны ли они? но, может быть, на единицу, т.е. начать с нуля? Или им не хватает Order = x? - person Marc Gravell; 29.06.2018
comment
@MarcGravell нет, я не устанавливаю свойство Order. Я добавил новый вопрос, показывающий мою проблему и все подробности о ней. Было бы лучше, если бы вы его проверили: stackoverflow .com / questions / 51092369 /. - person Iúri dos Anjos; 29.06.2018