2010-07-22 4 views
0

Я пишу службу .net WCF. Я написал несколько классов, которые я хочу вернуть к вызывающему коду из службы WCF; следовательно, я украшаю их атрибутом DataContract.Как использовать методы в классах, украшенных DataContractAttribute в клиенте WCF?

Предположим, что моя служба WCF называется FooService. Он содержит метод, называемый FooMethod, который возвращает объект типа FooData (который украшен атрибутом DataContract. Предположим, что FooData содержит список чисел и метод, называемый FooAverage, который возвращает среднее значение чисел.

В Visual Studio, я создаю новое приложение для использования службы. Я добавляю новую «Сервисную ссылку» в мою службу WCF и присваиваю ей пространство имен myWcfService. В моем клиентском коде я создаю прокси-класс и получаю подключение к службе. получить объект FooData из моего прокси-сервера, вызов метода myWcfService.FooMethod(). Он возвращает объект типа myWcfService.FooData, который является типом, определенным из метаданных FooService.

Теперь, когда у меня есть мой объект типа myWcfService.FooData, как я могу получить эти данные в объект типа FooData в качестве исходного типа из служебного кода, чтобы я мог позвонить FooData.FooAverage()?

Edit: Я полностью осведомлен о том, что данные поступают вниз по трубе в формате XML и что логика методов в классе, украшенный DataContract не получает возвращаемую службу; это не сериализуемо. Я спрашиваю: если я могу ссылаться на класс, который содержит класс DataContract, используемый в службе, есть ли простой способ де-сериализации данных в класс, из которого он был сериализован?

Я согласен принять ответ, что это невозможно с текущей картой .net.

ответ

2

WCF позволит повторно использовать типы, если они содержатся в проекте. Если ваши типы данных находятся в проекте Common, то эти типы повторно сериализуются (при условии, что они имеют конструктор по умолчанию и помечены для сериализации).

Это только половина вашего вопроса. Если вы хотите, чтобы ваш тип данных прокси на сервер реализовал реализацию вызова метода, вы можете захотеть Remoting (http://msdn.microsoft.com/en-us/library/ms973857.aspx) и использовать объект Proxy.

+0

Я хотел бы избежать Remoting - WCF сделал это устаревшее. Добавление операций в контракт на обслуживание - это способ сделать это в WCF. Однако, когда я читал вопрос, это не то, о чем он просил. –

0

Вы не можете.

Вы должны держать две вещи полностью отдельные:

  • у вас есть сервисные контракты которые определяют методы (украшенных [OperationContract] атрибутов)

  • эти методы могут понадобиться типы классов, которые вы определяете с использованием атрибутов [DataContract]

Характер WCF заключается в том, что параметры и типы, идущие от клиента к серверу, преобразуются в XML-представление, поэтому все, что вы можете отправить через провод в виде контрактов данных, - это необработанные данные - no behavior - вы не можете отправьте через класс DataContract и вызовите на нем метод.

В обычной настройке ваши классы данных на стороне клиента не такие же, как у них на стороне сервера - они просто смотрят то же самое в их XML-сериализованном формате. Все, что они разделяют, это их сериализация XML - элементы данных, которые сериализуются, не более того. WCF не какой-то метод вызова удаленной процедуры - он отправляет сообщения только для данных между клиентом и сервером (и это хорошая вещь! (Tm)).

Если вам нужно позвонить по методу, добавьте этот метод в ваш контракт на обслуживание как метод, украшенный атрибутом [OperationContract].

+0

-1 Конечно, он может использовать свой тип FooData на своей стороне (на стороне службы), если он хочет (как объясняет Nat Zauggs), и вызывать методы на нем. В вопросе ясно сказано, что он спрашивает о методе, который работает с сериализуемым состоянием объекта: поскольку состояние сериализовано в сервисе и десериализовано обратно в объект на клиенте, метод будет корректно работать на клиенте, как это было на сервере. Конечно, если метод зависит от частного несериализуемого состояния, то то же самое не применяется. –

+0

@ Крис Диксон: это было бы очень обескураженным и очень плохая практика - я бы сказал: просто ** никогда не делай этого! –

+0

Вопрос спрашивал, возможно ли это. Это. Что касается хорошей практики или нет: я согласен с вами в том, что при любом использовании, когда клиент и служба не разрабатываются (и версии) вместе, его плохая идея делиться типами между ними. НО, WCF был разработан не только для SOA, но и для замены существующих механизмов IPC и внутрипроцессного обмена (например, Remoting), и в некоторых сценариях это было бы вполне разумным дизайнерским решением. –

0

Вы можете продлить myWcfService.FooData с определением частичного класса и определить FooAverage() в клиенте, если исходный FooAverage() не имеет никаких зависимостей, которые запрещают это:

partial class FooData 
{ 
    public double FooAverage() { return Math.Average(Numbers); } 
} 

Но помните, что FooData является объектом передачи данных, и как таковой не имеет никакого частного состояния, а это значит, что вы можете поместить все данные в функции, не входящих в любом случае:

double average = Math.Average(foodata.Numbers); 
Смежные вопросы