Использование службы WCF для передачи экземпляра класса - PullRequest
2 голосов
/ 09 февраля 2012

У меня есть библиотека классов C # с примерно 50 классами с сотнями свойств. Создание экземпляров моих классов может занять некоторое время, поэтому в качестве оптимизации я подумывал о том, чтобы их экземпляры были созданы на сервере, а затем сервер передавал созданные экземпляры классов клиентскому приложению через службу WCF.

Кажется, все должно работать нормально. Однако, насколько я понимаю, если я хочу сделать это, мне нужно будет пометить не только каждый класс как [DataContract], но и каждое свойство как [DataMember]. Это правда? Кажется сумасшедшим, что это должно было быть сделано, особенно на каждой собственности. Есть ли способ просто сказать, что весь класс сериализуем без необходимости проходить через этот процесс?

Ответы [ 4 ]

3 голосов
/ 09 февраля 2012

Если вы используете [DataContract], вам нужно будет указать [DataMember] для каждого участника.

В качестве альтернативы - пометьте класс [Serializable], и сериализатор будет сериализовать все внутренние компоненты для васесли вы явно не скажете иначе ([Serializable] работает по принципу отказа, тогда как [DataContract] работает по подходу отказа).

Однако - в зависимости от того, что именно вы пытаетесь сделать - этоподход может быть ошибочным.

Когда вы передаете объект через WCF, вы на самом деле не передаете объект вообще - вы передаете копию объекта.Фактически, исходный объект будет сериализован, передан по проводу и десериализован на другом конце.Это означает, что клиент все еще должен создать экземпляр , восстановить экземпляр класса и затем заполнить все свойства.Вы можете ничего не получить, и, возможно, у вас будет довольно дорогой звонок с большим количеством данных, передаваемых по проводам.

Так что все зависит от того, что вы делаете.Если вы не возражаете против того, чтобы клиенты получали копию экземпляра, и если затраты связаны не с огромным объемом данных, а с другими причинами, такими как медленный доступ к базе данных, тогда все в порядке.В противном случае ваш подход может ничего вам не купить.

Кроме того, в удаленном взаимодействии .Net можно иметь ссылку на удаленный объект (т. Е. Ваш клиент может ссылаться на объект на сервере) - если типсам по себе происходит от MarshalByRefObject, но это не относится к WCF - у вас есть локальная копия.

2 голосов
/ 09 февраля 2012

Если я хочу это сделать, мне нужно не только пометить каждый класс как [DataContract], но также каждое свойство как [DataMember]. Это действительно правда?

Да и нет.

Если клиентский код не может импортировать сборку, содержащую эти классы, тогда да, вам нужно пометить их. Это сделано для того, чтобы WCF мог сообщать клиентам, как интерпретировать наборы результатов.

Если вы можете использовать общую сборку как в службе WCF , так и в клиентах (например, в виде библиотеки POCO), то вам не нужно применять эти атрибуты. WCF просто скажет клиентам ссылаться на сборку под ее строгим именем.

Вот как может выглядеть WSDL в случае № 2:

<wsdl:types>
  <xsd:schema targetNamespace = "http://tempuri.org/Imports">
    <xsd:import schemaLocation = "http://localhost:12902/MyService.svc?xsd=xsd0"
       namespace="http://tempuri.org/" />
    <xsd:import schemaLocation = "http://localhost:12902/MyService.svc?xsd=xsd1"
       namespace="http://schemas.microsoft.com/2003/10/Serialization/" />
    <xsd:import schemaLocation = "http://localhost:12902/MyService.svc?xsd=xsd2"
      namespace="http://schemas.datacontract.org/2004/07/MyAssembly.MyProject" />
  </xsd:schema>
</wsdl:types>

Где MyAssembly.MyProject выше относится к пространству имен в вашей сборке. Если вы перейдете по ссылке http://localhost:12902/MyService.svc?xsd=xsd2 (на вашем локальном компьютере, конечно), вы получите XSD, описывающий сущности, сериализованные в этом пространстве имен. Вам не нужно украшать класс. WCF делает все это для вас.

0 голосов
/ 09 февраля 2012

В сценарии реального отдельного клиент-сервер вы должны.(если вы не можете поделиться файлом.)

0 голосов
/ 09 февраля 2012

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...