2010-11-06 7 views
7

Я пытаюсь поиграть с WCF, и я думаю, что я ударил блок. Моя проблема в том, что я могу позвонить Add(double,double) и getPerson() из «Клиента». Тем не менее, я не могу назвать какие-либо методы объекта Person. Я разделил классы с помощью простых методов. Вот мои фрагменты кода, пожалуйста, дайте мне знать, что я делаю неправильно ..WCF возвращает объекты клиенту

Server Code

namespace Test.WebSvc{ 
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Sample")] 
    public interface ICalculator 
    { 
    [OperationContract] 
    double Add(double n1, double n2); 
    [OperationContract] 
    Person getPerson(); 
    } 


public class CalculatorService : ICalculator 
{ 
    public double Add(double n1, double n2) { return n1+n2 ; } 
    public Person getPerson(){ 
    Person tempPerson = new Person(); 
    return tempPerson; 
    } 
} 

[DataContract] 
public class Person{ 
[OperationContractAttribute] 
public string toString(){ 
return "This is a Person Object"; 
} 

Client Code

ServiceRef1.CalculatorClient client = ServiceRef1.CalculatorClient();//works 
Console.WriteLine(client.Add(1.0,2.0)); //this too works 
ServiceRef1.Person p = client.getPerson(); // this is OK., but is not doing what I wanted it to do 
Console.WriteLine(p.toString()); // I do not get "This is Person Object" 

Я предполагаю, что-то случилось с моим классом Person декларации .. но не знаю, что мне делать или что мне не хватает.

Спасибо!

ответ

8

Вы смешиваете две концепции с вашим типом Person - то, что вы делаете, не будет работать.

Вы установили атрибут DataContract на тип Person. Это правильно, потому что у вас есть служба, возвращающая Person. Объект Person будет сериализован и возвращен вашему сервисному клиенту (CalculatorClient в этом случае).

Вы должны определить Person так:

[DataContract] 
public class Person 
{ 
    [DataMember] 
    public string Description { get; set; } 
} 

И в службе калькулятор:

public Person getPerson() 
{ 
    Person tempPerson = new Person(); 
    tempPerson.Description = "This is a Person Object"; 
    return tempPerson; 
} 

Это потому, что работа вашего Person объекта является для хранения данных, и носить его от сервера к клиенту , Это не его задача определить методы/операции, которые должны выполняться в классах службы (например, CalculatorService). Добавление атрибута OperationContract не волшебным образом превращает объект передачи данных в службу.

+0

Потребовал мне минуту, чтобы понять, что DataContract не входит в пространство имен ServiceModel. Его в System.Runtime.Serialization, и вам также нужно будет добавить ссылку в свой проект к ней – Knightsy

10

Да, вы столкнулись с барьером - WCF - это система на основе сообщений, которая только обменяла сериализованными данными либо в формате XML, либо в формате JSON в текстовом или двоичном формате. Он делает не, но передайте «полные» объекты .NET с их полными возможностями, такими как методы и все такое (как это должно быть). Он предназначен для взаимодействия с , и я не вижу, как мог работать Ruby или PHP-клиент вызов метода на объект .NET).

WCF не предназначен для удаленного доступа к объектам - он просто передает сообщения между клиентом и сервером. Поэтому все, что вы можете выразить в XML-схеме (атомные типы, что-то вроде наследования и композиции), может быть сериализовано и отправлено между двумя сторонами.

Все, что не может быть смоделированным в XML-схеме, как генераторы, интерфейсы, методы/код - не может быть передано между клиентом и сервером.

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

Снова: это работает отлично, пока вы управляете обоими концами связи, а на обоих концах используется .NET. Любая совместимость выходит из окна с таким подходом.

+0

+1 Объяснение сериализованных данных –

Смежные вопросы