2014-10-10 4 views
1

Рассмотрим следующие два контракта данных:WCF разница между типом и ServiceKnownType

[DataContract]  
public class Item 
{ 
    [DataMember] 
    public int X; 
} 

[DataContract] 
public class SubItem : Item 
{ 
    [DataMember] 
    public int Y; 
} 

В чем разница между использованием двух контрактов данных в следующих договоров об оказании услуг.

[ServiceContract] 
public interface IInterface 
{ 
    [OperationContract] 
    [ServiceKnownType(typeof(SubItem))] 
    void Save(Item i); 
} 

[ServiceContract] 
public interface IInterface 
{ 
    [OperationContract] 
    void Save(SubItem i); 
} 

Может ли первый быть вызван с подклассом предмета, кроме SubItem? Если да, то что означает значение ServiceKnownType?

ответ

1

Когда вы используете в первом случае, учитывая, что SubItem Наследуется от Item вы говорите вашему WebService, когда он разоблачить его WSDL принять во внимание десериализации SubItem типа, как это может быть используется в качестве аргумента для параметра Item (принципал полиморфизма), в противном случае конечные точки получателя не смогут передать SubItem в качестве аргумента для метода, даже если тип был десериализован на стороне клиента с помощью DataMemberAttribute.

Note, что с ServiceKnownType применяется класс будет сериализовать, даже если SubItem не был отмечен тха DataMember атрибутом

вот пример

служба боковой

using System.Runtime.Serialization; 
using System.ServiceModel; 

namespace WcfService1 
{ 

    [ServiceContract] 

    public interface IService1 
    { 

     [OperationContract] 
     [ServiceKnownType(typeof(SubItem))] // try to comment this and uncomment GetDataUsingDataContract 
     Item GetData(int value); 

     //[OperationContract] //here try to comment/uncomment and see if the subitem was deserialized at client side the operation on server side will not be executed 
     //Item GetDataUsingDataContract(SubItem item); 

     //// TODO: Add your service operations here 
    } 


    // Use a data contract as illustrated in the sample below to add composite types to service operations. 
    [DataContract] 

    public class Item 
    { 
     bool boolValue = true; 
     string stringValue = "Hello "; 

     [DataMember] 
     public bool BoolValue 
     { 
      get { return boolValue; } 
      set { boolValue = value; } 
     } 

     [DataMember] 
     public string StringValue 
     { 
      get { return stringValue; } 
      set { stringValue = value; } 
     } 
    } 
    //[DataContract] 
    public class SubItem:Item 
    { 
     private string _subItemVersion; 
     //[DataMember] 
     public string SubItemToStringValueVersion { get { return _subItemVersion; } set { _subItemVersion = value; } } 
    } 
} 

Client Side

static void Main(string[] args) 
     { 
      Service1Client service1Client = new Service1Client(); 
      var result = service1Client.GetData(5); 
      if (result is SubItem) 
      { 

      } 
     } 
0

Да, первый может быть вызван, но если фактический тип неизвестен службе, он может использовать только те элементы, которые находятся в типе Item.

В этом случае ServiceKnownType не имеет значения/значения для сервера, поскольку он не используется ни в параметрах, ни в возвращаемых типах.

Например, если операция сохранения вернет элемент, а фактический элемент будет SubItem, он сериализует результат как SubItem. Для этого атрибут ServiceKnownType.

0

Первый метод Save можно назвать только с Пункт или подпозиция например, но второй один принимает только подпозиция экземпляра.

Цель ServiceKnownTypeAttribute указывает типы, которые должны быть включены для рассмотрения во время десериализации. Для получения дополнительной информации смотрите на Data Contract Known Types и ServiceKnownTypeAttribute Class

0

В чем разница между использованием двух контрактов данных в следующих контрактах на обслуживание? С первым вы можете передать объект типа Item или SubItem, поскольку SubItem отображается как KnownType. Во втором вы можете передавать только элементы SubItem.

Может ли первый вызов быть вызван подклассом предмета, кроме SubItem? Если да, то что означает значение ServiceKnownType? Нет, он не может быть вызван с подклассом предмета, отличного от SubItem.Чтобы иметь возможность сделать это, вам придется выставить его как KnownType.