В WCF, классы передачи данных наследуют друг другу?


В службе WCF у меня есть два класса с атрибутом [DataContract]. Один из этих классов имеет отношение" is-a " с другим - так что класс B может наследовать от класса A. Однако, когда я настраиваю наследование между этими двумя классами, оба обозначаются атрибутом [DataContract], метаданные не загружаются при тестировании служб.

Возможно ли это в WCF? Может быть, я упустил еще один атрибут?

[DataContract]
public class A
{        
    [DataMember]
    public MyCustomType AValue1{ get; set; }

    [DataMember]
    public MyCustomType AValue2 { get; set; }
}

[DataContract]
public class B: A
{       
   [DataMember]
   public double BValue1{ get; set; }

   [DataMember]
   public double BValue2 { get; set; }
}

Примечание: пользовательские типы также определяются с помощью данных контракты.

UPDATE : ниже приведена Ошибка:

Ошибка: не удается получить метаданные из http://localhost:8002/GISDataServices/mex если это служба Windows (R) Communication Foundation, к которой у вас есть доступ, убедитесь, что вы включили публикацию метаданных по указанному адресу. Для получения справки о публикации метаданных обратитесь к документации MSDN по адресу http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata обмен URI ошибки: http://localhost:8002/GISDataServices/mex метаданные содержат ссылку, которая не может быть разрешена: 'http://localhost:8002/GISDataServices/mex ". Receivera:InternalServiceFaultсервер не смог обработать запрос из-за внутренней ошибки. Для получения дополнительной информации об ошибке включите IncludeExceptionDetailInFaults (либо из ServiceBehaviorAttribute, либо из поведения конфигурации ) на сервере, чтобы отправить информацию об исключении обратно клиенту или включите трассировку в соответствии с документацией Microsoft .NET Framework 3.0 SDK и просмотрите журналы трассировки сервера.HTTP GET Error URI: http://localhost:8002/GISDataServices/mex произошла ошибка загрузки 'http://localhost:8002/GISDataServices/mex ". Сбой запроса с состоянием http 400: неверный запрос.

Обновление 2: смотрите мой ответ ниже.

3 24

3 ответа:

Да, но вам нужно украсить базовый класс с помощью [KnownTypeAttribute], построив его с типом производного класса. Например:

[DataContract]
[KnownType(typeof(B))]
public class A
{
   [DataMember]
   public string Value { get; set; }
}

[DataContract]
public class B : A
{
   [DataMember]
   public string OtherValue { get; set; }
}

Ладно, я понял вопрос. Ответ таков...Я идиотка. Это не имело никакого отношения к наследству. В базовом классе у меня был член контракта данных без предложения свойства " set "- только "get". Дох!!! Включение пункта "набор" заставило его работать как заклинание.

Извините за путаницу.

На основе этого теста он должен работать нормально. Имеют ли оба класса конструкторы по умолчанию? Вы используете авто-свойства. Обратите внимание, что в этом базовом примере атрибуты не требуются. Кроме того, как упоминал Дэвид Мортон, в зависимости от того, какой элемент вы возвращаете, вам может понадобиться атрибут KnownType, я не на 100%, но известный тип может быть включен в контракт на операцию.

class Program
{
    static void Main(string[] args)
    {
        var serializer = new DataContractSerializer(typeof(Employee));

        var employee = new Employee() { Name="Joe", Salary=100000  };
        using (var ms = new MemoryStream())
        {
            serializer.WriteObject(ms, employee);

            ms.Position = 0;

            var newEmployee = serializer.ReadObject(ms) as Employee;
        }

        Console.ReadKey();

    }
}

[DataContract]
public class Employee : Person
{
    [DataMember]
    public decimal Salary { get; set; }
}

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

[ServiceContract]
interface IEmployeeService
{
    [OperationContract]
    Person GetPerson();

    [OperationContract]
    Employee GetEmployee();

    [OperationContract]
    [KnownType(typeof(Employee))]
    Person GetEmployeeAsPerson();
}