2013-04-05 3 views
2

Мне нужно вызывать операции webservice с помощью стандартного wsdl, но объекты данных должны быть разными в клиенте и на сервере.Как использовать интерфейс как DataContract в WCF

Использование интерфейсов для объектов данных в общей библиотеке, создание прокси-классов для него в клиенте и на сервере.

Затем я объявляю рабочий договор с использованием интерфейса, но WCF его не распознает.

Я еще не пробовал использовать DataContractSerializerПомощь и набор известных типов, пока не удался.

Кто-нибудь может мне помочь? Я приложил полное решение с более подробной информацией.

public interface Thing 
{ 
    Guid Id {get;set;} 
    String name {get;set;} 
    Thing anotherThing {get;set;} 
} 

[DataContract] 
public class ThingAtServer: BsonDocument, Thing // MongoDB persistence 
{ 
    [DataMember] 
    Guid Id {get;set;} 
    //... 
} 

[DataContract] 
public class ThingAtClient: Thing, INotifyPropertyChanged // WPF bindings 
{ 
    [DataMember] 
    Guid Id {get;set;} 
    //... 
} 

[ServiceContract] 
public interface MyService 
{ 
    [OperationContract] 
    Thing doSomething(Thing input); 
} 

Нажмите здесь делают увидеть Sample project on GitHub с TestCases

+0

You» re, не показывающий, как определяется «Вещь» - тоже ли это «[DataContract]»? Как насчет '[BsonDocument]'? Как правило, вы должны определить ** отдельные **, elightweight (DTO-style) объекты для служб WCF - не наследуйте от таких вещей, как базовый класс MongoDB - вам не нужно и не хотите сериализовать все это состояние над вашим WCF оказание услуг.... –

+0

Также: WCF представляет собой систему передачи сообщений на основе XML - поэтому все, что вы проходите в WCF, должно быть представлено в XML-схеме (XSD); интерфейсы ** не ** поддерживаются XSD - вам нужно использовать ** конкретные классы ** (и дженерики не поддерживаются ни ...) –

ответ

2

я создал службы WCF с контрактом:

[OperationContract] 
CompositeTypeServer GetDataUsingDataContract(CompositeTypeServer composite); 

Мои CompositeTypeServer выглядит следующим образом:

[DataContract(Namespace = "http://enes.com/")] 
public class CompositeTypeServer 
{ 
    [DataMember] 
    public bool BoolValue { get; set; } 

    [DataMember] 
    public string StringValue { get; set; } 
} 

Тогда я создал cl диент проект с типом CompositeTypeClient:

[DataContract(Namespace = "http://enes.com/")] 
public class CompositeTypeClient 
{ 
    [DataMember] 
    public bool BoolValue { get; set; } 

    [DataMember] 
    public string StringValue { get; set; } 
} 

Затем я добавил ссылку на мою службу и выбрал для повторного использования типов. Все работало как шарм. Я смог использовать на стороне клиента CompositeTypeClient.

Итак, трюк состоял в том, чтобы указать пространство имен для DataContract, чтобы они соответствовали как клиенту, так и службе.

[DataContract(Namespace = "http://enes.com/")] 

PS. Я могу предоставить полное рабочее решение VS по запросу.

0

Основано на ServiceKnownTypeAttribute (MSDN documentation), я изменил какие типы ожидали в зависимости от ситуации. Основная идея реализована в классе XHelper, ответственность вернуть правильный Type[] в зависимости от ситуации:

public static class XHelper 
{ 

    public static Boolean? IsClient = null; 
    public static Type[] ClientTypes; 
    public static Type[] ServerTypes; 

    public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider pProvider) 
    { 
     if (!IsClient.HasValue) 
      throw new Exception("Invalid value"); 
     if (IsClient.Value) 
      return ClientTypes; 
     return ServerTypes; 
    } 
} 

Вы должны включить ServiceKnownType тег в интерфейсе, который имеет те ServiceContract знать XHelper класс.

[ServiceContract(Namespace = MyProxyProvider.MyNamespace)] 
[ServiceKnownType("GetKnownTypes", typeof(XHelper))] 
public interface MyService 
{ 
    [OperationContract] 
    Thing2 CopyThing(Thing1 input); 
} 

В начале испытательного блока, который был проинформирован о праве Type[] для любой ситуации:

[AssemblyInitialize] 
    public static void TestInitialize(TestContext pContext) 
    { 
     XHelper.ClientTypes = new Type[] { typeof(Thing1ProxyAtClient), typeof(Thing2ProxyAtClient), typeof(Thing2ProxyAtClient) }; 
     XHelper.ServerTypes = new Type[] { typeof(Thing1ProxyAtServer), typeof(Thing2ProxyAtServer), typeof(ThingNProxyAtServer) }; 
    } 

Нажмите здесь действительно увидеть окончательный код Sample project on GitHub с TestCases

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

  • Нет связанных вопросов^_^