Только базовый класс возврата службы WCF

Я работаю над службой WCF и пытаюсь очистить код. Проблема, с которой я сталкиваюсь, заключается в том, что у меня есть базовый тип данных, который я хочу отправить в качестве результатов от службы клиенту; однако в самом служебном коде в основном используются классы, производные от базы, с дополнительными свойствами для обработки. У клиента вообще нет причин знать об этом.

Прямо сейчас я могу заставить это работать, но только если я определю производные классы в общей библиотеке. Я не хочу, чтобы они там были, поскольку они предназначены исключительно для службы.

Ниже приведен пример, показывающий проблему. Все три файла находятся в разных проектах в одном решении.

Common.IPersonService.cs

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

namespace Common
{
    [ServiceContract]
    public interface IPersonService
    {
        [OperationContract(Name = "GetPersonById")]        
        Person GetPersonById(int id);
    }

    [DataContract(Name = "Person")]
    public class Person
    {
        [DataMember]
        public int Id { get; set; }

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

WcfClient.Program.cs

using System;
using System.ServiceModel;
using Common;

namespace WcfClient
{
    class Program
    {
        static void Main(string[] args)
        {
            var binding = new NetTcpBinding();
            var endpoint = new EndpointAddress("net.tcp://localhost:8001/WcfTest/");
            var factory = new ChannelFactory<IPersonService>(binding, endpoint);

            IPersonService service = null;

            try
            {
                service = factory.CreateChannel();

                Person result = service.GetPersonById(5);
                Console.WriteLine(result.Name);

                ((ICommunicationObject)service).Close();

                Console.ReadLine();
            }
            catch(Exception ex)
            {                
                Console.WriteLine(ex.Message);
                Console.ReadLine();
            }
        }
    }
}

WcfService.Program.cs

using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.ServiceModel.Description;
using Common;

namespace WcfService
{
    [DataContract(Name = "Person")]
    public class Contact : Person
    {
        public string Address { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (ServiceHost serviceHost = new ServiceHost(typeof(PersonService)))
            {
                serviceHost.Open();

                Console.WriteLine("Service started");
                Console.ReadLine();
            }
        }
    }

    public class PersonService : IPersonService
    {

        private Dictionary<int, Contact> _testData = new Dictionary<int, Contact>();

        public PersonService()
        {
            Random rnd = new Random();

            for (int i = 0; i < 100; i++)
            {
                _testData.Add(i + 1, new Contact()
                {
                    Id = i + 1,
                    Name = Guid.NewGuid().ToString(),
                    Address = Guid.NewGuid().ToString()
                });
            }
        }

        public static void Configure(ServiceConfiguration config)
        {
            config.AddServiceEndpoint(typeof(IPersonService), new NetTcpBinding(), "net.tcp://localhost:8001/WcfTest/");

            config.Description.Behaviors.Add(new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true });
        }

        public Person GetPersonById(int id)
        {
            return _testData[id];
        }

        public Person GetValueByKey(string key)
        {
            return null;
        }
    }
}

Получено следующее исключение:

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.9780000'.

Теперь, если я перенесу класс Contact из проекта WcfService и помещу его в общий проект, он заработает. Как уже было сказано, я бы предпочел не засорять общую библиотеку элементами, специфичными для реализации службы.

Спасибо!

Вам необходимо иметь класс Contact в разделяемой библиотеке, потому что и сервер, и клиент должны знать, как сериализовать и десериализовать переданные данные. Общая библиотека содержит КОНТРАКТЫ между сервером и клиентом, операции И контракты данных. Это не «мутно».

KBO 02.05.2018 08:17

@KBO Непонятная часть состоит в том, что класс «Контакт» в моей реальной программе содержит только данные и функции, которые необходимы самому процессу сервера, и не должны передаваться через службу клиенту. Так что добавление класса, о котором клиент никогда не должен знать, в разделяемую библиотеку - непонятно. Класс «Контакт» просто естественным образом расширился на базовый класс, поэтому его было целесообразно наследовать. На данный момент я избавился от наследования и просто сделал Person членом Contact, чтобы его можно было отправлять самостоятельно.

Will E. 02.05.2018 17:45

Включите ведение журнала сообщений wcf docs.microsoft.com/en-us/dotnet/framework/wcf/diagnostics/…. Без сомнения, будет больше подробностей об исключении.

fanuc_bob 02.05.2018 18:37
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
76
0

Другие вопросы по теме