Атрибуты производного типа не десериализованы в клиенте WCF, даже если используется KnownType - PullRequest
0 голосов
/ 23 сентября 2011

У меня есть следующие типы:

public enum MyEnum
{
    Value1,
    Value2
}

[DataContract]
public class Configuration
{
    [DataMember]
    public MyEnum MyValue { get; set; }
    [DataMember]
    public Credentials CredentialValues { get; set; }
}

[DataContract, KnownType(typeof(CustomCredentials))]
public class Credentials 
{

}

[DataContract]
public class CustomCredentials : Credentials 
{
    [DataMember]
    public string Property1 { get; set; }
    [DataMember]
    public string Property2 { get; set; }
}

И в моем интерфейсе службы у меня есть функция, которая возвращает экземпляр Configuration со свойством CredentialValues, установленным для полностью заполненного экземпляра CustomCredentials. Я не получаю ошибок от клиента или сервера, но пока данные сериализуются на сервере и принимаются клиентом, свойства в CustomCredentials никогда не имеют значения. Что мне нужно изменить здесь, чтобы правильно десериализовать эти свойства на клиенте?

Для справки, соединение между клиентом и сервером устанавливается с DuplexChannelFactory по NetTcpBinding с использованием проекта контракта на данные / сервис, который совместно используется клиентом и сервисными приложениями (сервис размещается самостоятельно), нет никаких типов прокси-серверов служб, которые могли бы быть восстановлены.

1 Ответ

0 голосов
/ 26 сентября 2011

Добавил этот код в проект Contracts вместе с вашими DataContracts.

[ServiceContract(Namespace = "http://schemas.platinumray.com/duplex", SessionMode = SessionMode.Required, CallbackContract = typeof(IService1Callback))]
public interface IService1
{
    [OperationContract(IsOneWay = true)]
    void GetData();
}

public interface IService1Callback
{
    [OperationContract(IsOneWay = true)]
    void SetData(Configuration config);
}

Создан сервис.

public class Service1 : IService1
{
    public void GetData()
    {
        var x = new Configuration()
        {
            MyValue = MyEnum.Value1,
            CredentialValues = new CustomCredentials { Property1 = "Something", Property2 = "Something else" }
        };
        OperationContext.Current.GetCallbackChannel<IService1Callback>().SetData(x);
    }
}

class Program
{
    static void Main(string[] args)
    {

        using (ServiceHost host = new ServiceHost( typeof(Service1), new Uri[] { new Uri("net.tcp://localhost:6789") }))
        {
            host.AddServiceEndpoint(typeof(IService1), new NetTcpBinding(), "Service1");
            host.Open();
            Console.ReadLine();
            host.Close();
        }
    }
}

Создан клиент.

public class CallbackHandler : IService1Callback
{
    public void SetData(Configuration config)
    {
        Console.WriteLine(config.CredentialValues.GetType().Name);
        Console.WriteLine(((CustomCredentials)config.CredentialValues).Property1);
        Console.WriteLine(((CustomCredentials)config.CredentialValues).Property2);
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Setup the client
        var callbacks = new CallbackHandler();
        var endpoint = new EndpointAddress(new Uri("net.tcp://localhost:6789/Service1"));
        using (var factory = new DuplexChannelFactory<IService1>(callbacks, new NetTcpBinding(), endpoint))
        {
            var client = factory.CreateChannel();
            client.GetData();
            Console.ReadLine();
            factory.Close();
        }
    }
}

Выводит следующее, как и ожидалось:

CustomCredentials
Something
Something else

Так что на самом деле это работало без изменения каких-либо ваших контрактов на данные ... Те же самые результаты, если я вернусь к операции twoway и просто верну Configuration напрямую, без использования обратного вызова.

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

Я что-то пропустил?

...