WCF Разница между типом и ServiceKnownType

1

Рассмотрим следующие два контракта данных:

[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?

Теги:
wcf

4 ответа

1
Лучший ответ

Когда вы используете для первого случая, когда SubItem from Item вы SubItem сервису, когда он раскрывает его WSDL, SubItem десериализацию типа 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; } }
    }
}

Сторона клиента

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

            }
        }
0

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

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

0

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

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

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

0

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

Цель ServiceKnownTypeAttribute - указать типы, которые должны быть включены для рассмотрения во время десериализации. Дополнительные сведения см. В разделе " Известные типы данных" и " ServiceKnownTypeAttribute"

Ещё вопросы

Сообщество Overcoder
Наверх
Меню