Гость
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / Как передать интерфейс через wcf / 15 сообщений из 15, страница 1 из 1
24.06.2011, 18:26
    #37324200
Mr_GOD
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Только недавно познакомился с wcf. Пока особо глубокого понимания нет.
Столкнулся с такой проблемой не получается передать класс, который наследован от интерфейса

Класс для передачи:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
[DataContract]
public class DataContainer : IDataContainer
{
    [DataMember]
    public List<string> Columns { get; set; }

    [DataMember]
    public List<List<string>> Rows { get; set; }
}

Интерфейс-предок класса:
Код: plaintext
1.
2.
3.
4.
5.
public interface IDataContainer
{
    List<string> Columns { get; set; }

    List<List<string>> Rows { get; set; }
}

Реализация сервиса:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
public class Service : IService
{
    public IDataContainer GetAllProducts()
    {
        DataAccessEngine dae = DataAccessEngine.Instance();
        IDataContainer result = dae.GetAllProducts(); // public IDataContainer GetAllProducts()
        return result;
    }
}

На клиенте получаю исключение "The underlying connection was closed: The connection was closed unexpectedly."
Если не наследовать класс от интерфейса то все работает нормально.
Я предполагаю что на интерфейс тоже нужно повесить кокой-то атрибут но пока не смог найти какой.
...
Рейтинг: 0 / 0
26.06.2011, 10:56
    #37325030
D129
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Mr_GOD,

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

:)

Если вы учитесь - и вам надо именно так - то маловато информации.

Включите диагностику в конфигурации сервиса и клиента - и после обращения и обвала посмотрите полученные логи. Там обычно все написано точно.
...
Рейтинг: 0 / 0
26.06.2011, 13:47
    #37325100
Mr_GOD
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
D129,
я учусь. Можешь подробнее рассказать о том что надо сделать что бы посмотреть в логи?
...
Рейтинг: 0 / 0
26.06.2011, 14:06
    #37325108
Mr_GOD
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Я попробовал тоже самое с DataTable. Ошибка такая же...
...
Рейтинг: 0 / 0
26.06.2011, 15:41
    #37325162
МихаилР
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Не проверял именно вашу ситуацию (наследование от интерфейса), но в целом, если вы наследуете один контракт данных от другого и работаете через базовый контракт (как у вас в примере операция возвращает IDataContainer, хотя в реальности за ним скрывается DataContainer) - то у базового контракта нужно указывать список всех унаследованных классов через атрибут KnownType (или у самого сервиса через ServiceKnownType).

Т.е. в вашем случае следовало объявить:
Код: plaintext
1.
2.
3.
4.
5.
6.
[KnownType(typeof(DataContainer))]
public interface IDataContainer
{
    List<string> Columns { get; set; }

    List<List<string>> Rows { get; set; }
}

Возможно также, вам следует перенести определение контрактов в базовый класс (хотя вообще-то определения контрактов вообще не обязательны - главное чтобы свойства были публичными).
Но вообще вы используете довольно необычный вариант так что может статься он в принципе не заработает.
...
Рейтинг: 0 / 0
26.06.2011, 17:18
    #37325192
Mr_GOD
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Вся проблема в том что у атрибутов [KnownType] и [DataContract] есть ограничение "It is only valid on 'class, struct' declarations."
...
Рейтинг: 0 / 0
27.06.2011, 15:18
    #37326027
МихаилР
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Вы меня зацепили :) - решил все-таки найти решение.

Посмотрите на такой вариант:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
public interface IDataContainer
{
     List<string> Columns { get; set; }
     List<List<string>> Rows { get; set; }
}
    
public class DataContainer : IDataContainer
{       
    public  List<string> Columns { get; set; }
    public  List<List<string>> Rows { get; set; }
}

[ServiceContract]
[ServiceKnownType(typeof(DataContainer))]
public interface IService1
{
    [OperationContract]
    IDataContainer GetAllProducts();
}

public class Service : IService1
{
   public IDataContainer GetAllProducts()
   {
       IDataContainer result = new DataContainer() { Columns = null, Rows = null };
       return result;
   }
}

Т.к. у interface нельзя объявлять ни [DataContract], ни [Serializable], то обходимся без них (правда упралять процессом сериализации уже будет нельзя.
А чтобы работало наследование объявляем у контракта сервиса [ServiceKnownType(typeof(DataContainer))].

Подойдет такой вариант?
...
Рейтинг: 0 / 0
28.06.2011, 12:54
    #37327090
Mr_GOD
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
МихаилР,

Спасибо большое))) Работает! Как оказалось все гораздо проще чем я думал.
...
Рейтинг: 0 / 0
28.06.2011, 13:05
    #37327114
Mr_GOD
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Упс... Я погорячился) Не заметил что приведение типов. А клиент как не знал об интерфейсе так и не знает... Почитал литературу, мне почему то кажется уже что передать класс через интерфейс клиенту не возможно.
...
Рейтинг: 0 / 0
28.06.2011, 13:22
    #37327157
Mr_GOD
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Выкладываю солюшн по вс 2010. Может кто-нибудь все таки сможет решить эту проблем
...
Рейтинг: 0 / 0
28.06.2011, 14:06
    #37327250
МихаилР
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Mr_GODУпс... Я погорячился) Не заметил что приведение типов. А клиент как не знал об интерфейсе так и не знает... .
Вот это уточните, пожалуйста - что смущает (где приведение, где его не должно было быть)?

Mr_GODПочитал литературу, мне почему то кажется уже что передать класс через интерфейс клиенту не возможно.
Ну вообще это логично - интерфейс с точки зрения контрактов данных - это пустышка, "контракт". Поэтому передавать его на клиента не имеет смысла - все интерфейсы передаются как object, но при этом, скрывающийся за ним объект передается корректно.

Если вы хотите, чтобы интерфейсы были и на клиенте - вы можете сами вручную доработать генерацию proxy (сгенерировать свои). Это будет не слишком переносимо, но работать будет.

А вообще интересно - почему вы так уперлись в интерфейсы? Почему не хотите использовать классы?
...
Рейтинг: 0 / 0
28.06.2011, 14:11
    #37327265
Mr_GOD
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
МихаилР,
МихаилРВот это уточните, пожалуйста - что смущает (где приведение, где его не должно было быть)?
Я в теле сервиса приводил интерфейс к классу и передавал именно класс. Когда проверял то что вы предложили то забыл про это. И по этому все заработало.

А что касается интерфейсов в принципе, ну люблю я в общем интерфейсы и меня заинтересовала именно абстрагирование от конкретных классов. Просто если бы у меня было бы несколько реализаций данного интерфейса то передавать их бы было очень проблематично. Вот я и начал экспериментировать. Как оказалось достаточно гибкую штуку пописать не получилось((
...
Рейтинг: 0 / 0
28.06.2011, 14:34
    #37327297
МихаилР
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Mr_GODЯ в теле сервиса приводил интерфейс к классу и передавал именно класс. Когда проверял то что вы предложили то забыл про это. И по этому все заработало.
Все равно не понял.
Я вот передаю сам интерфейс - посмотрите мой пример, он работает.
Почему вы не можете сделать так же - не понимаю.

Mr_GODА что касается интерфейсов в принципе, ну люблю я в общем интерфейсы и меня заинтересовала именно абстрагирование от конкретных классов.
В принципе, можно перейти на абстрактные классы, если только не требуется множественная реализация нескольких интерфейсов.
...
Рейтинг: 0 / 0
28.06.2011, 20:15
    #37327868
Mr_GOD
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Все я понял общий смысл. Я имел в виду что клиент не получает сигнатуры интерфейса. вобщем я понял что их передавать приводя к типу object. Спасибо воббщем
...
Рейтинг: 0 / 0
29.06.2011, 20:27
    #37329594
Верблюд
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как передать интерфейс через wcf
Mr_GOD,

Вот это вот все вынести в отдельную библиотеку и прицепить ее в проекты как сервера, так и клиента, а не использовать индусский клиентогенератор студии.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
public interface IDataContainer
{
     List<string> Columns { get; set; }
     List<List<string>> Rows { get; set; }
}
    
public class DataContainer : IDataContainer
{       
    public  List<string> Columns { get; set; }
    public  List<List<string>> Rows { get; set; }
}

[ServiceContract]
[ServiceKnownType(typeof(DataContainer))]
public interface IService1
{
    [OperationContract]
    IDataContainer GetAllProducts();
}
...
Рейтинг: 0 / 0
Форумы / WCF, Web Services, Remoting [игнор отключен] [закрыт для гостей] / Как передать интерфейс через wcf / 15 сообщений из 15, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]