none
Передача типа данных на сервер RRS feed

  • Вопрос

  • Здравствуйте, есть несколько классов, например (обращение к базе идет через NHibernate):

        public class Faculty : EntityBase
        {
            public virtual string name { get; set; }
        }
    
        public class Department : EntityBase
        {
            public virtual Faculty facultyId { get; set; }
            public virtual string name { get; set; }
        }
    
        public class Specialty : EntityBase
        {
            public virtual Department departmentId { get; set; }
            public virtual string name { get; set; }
        }

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

    С сервера я могу получить List<Department>, но так придется писать для каждого метода.

    [OperationContract] List<Department> RequestBD(string requestString);


    public List<Department> RequestBD(string requestString) { IRepository<Department> entity = GetSessionManager().CreateRepository<Department>(); return entity.LinqRequest<Department>(requestString); }

    На клиенте я вызываю метод так:

                    List<Department> list = connectServer.RequestBD("facultyId.id = 1").ToList();

    Хотелось бы, чтобы выглядело все вот так, тогда метод будет один и универсальный:

    [OperationContract] List<T> RequestBD<T>(string requestString);


    public List<T> RequestBD<T>(string requestString) { IRepository<T> entity = GetSessionManager().CreateRepository<T>(); return entity.LinqRequest<T>(requestString); }

    Клиент:

                    List<Department> list = connectServer.RequestBD<Department>("facultyId.id = 1").ToList();

    На List<T> WCF конечно же ругается, но я могу сделать сериализацию. Проблема в том, как мне передать на сервер тип, к которому приводить данные?


    • Изменено Artemy.Sh 16 марта 2012 г. 0:10
    16 марта 2012 г. 0:10

Ответы

  • Здравствуйте.

    Сделать обобщенные методы в WCF не получится, так как они нарушают принципы на которых строится WCF, все типы должны быть заранее известны.

    Посмотрите обсуждение на RSDN по данному вопросу - WCF & Generic Methods

    Также можно попробовать обходное решение, предложенное на зарубежном форуме - WCF and Generics


    Для связи [mail]

    • Помечено в качестве ответа Artemy.Sh 20 марта 2012 г. 11:19
    16 марта 2012 г. 7:42
    Модератор
  • Спасибо, буду пробовать обходное решение. У меня возникла ещё одна проблема, возможно ли сделать так, чтобы имея название класса, например "Faculty" сделать List<"Faculty">?

    Примерно так, используя рефлексию:

    using System;
    using System.Collections.Generic;
    
    namespace Reflection
    {
        class Program
        {
            static void Main(string[] args)
            {
                Type genericType = typeof(List<>);
                Type typeArgument = Type.GetType("Reflection.Faculty");
                Type[] typeArguments = { typeArgument };
                Type newType = genericType.MakeGenericType(typeArguments);
                object createdTypeListFaculty = Activator.CreateInstance(newType);
                Console.WriteLine(createdTypeListFaculty.GetType().ToString());
                Console.Read();
            }
    
        }
        public class Faculty
        {
            public string Test = "Hello";
        }
    }

    • Помечено в качестве ответа Artemy.Sh 20 марта 2012 г. 11:19
    20 марта 2012 г. 6:03
    Модератор
  • Самый лёгкий способ это, вместо:

    object createdTypeListFaculty = Activator.CreateInstance(newType);
    объявить так:

    dynamic createdTypeListFaculty = Activator.CreateInstance(newType);
    А потом работаете с этой переменной так как обычно, просто IntelliSense в Visual Studio не будет работать.

    • Помечено в качестве ответа Artemy.Sh 20 марта 2012 г. 11:19
    20 марта 2012 г. 10:27
    Модератор

Все ответы

  • Здравствуйте.

    Сделать обобщенные методы в WCF не получится, так как они нарушают принципы на которых строится WCF, все типы должны быть заранее известны.

    Посмотрите обсуждение на RSDN по данному вопросу - WCF & Generic Methods

    Также можно попробовать обходное решение, предложенное на зарубежном форуме - WCF and Generics


    Для связи [mail]

    • Помечено в качестве ответа Artemy.Sh 20 марта 2012 г. 11:19
    16 марта 2012 г. 7:42
    Модератор
  • Спасибо, буду пробовать обходное решение. У меня возникла ещё одна проблема, возможно ли сделать так, чтобы имея название класса, например "Faculty" сделать List<"Faculty">?
    16 марта 2012 г. 9:39
  • Спасибо, буду пробовать обходное решение. У меня возникла ещё одна проблема, возможно ли сделать так, чтобы имея название класса, например "Faculty" сделать List<"Faculty">?

    Примерно так, используя рефлексию:

    using System;
    using System.Collections.Generic;
    
    namespace Reflection
    {
        class Program
        {
            static void Main(string[] args)
            {
                Type genericType = typeof(List<>);
                Type typeArgument = Type.GetType("Reflection.Faculty");
                Type[] typeArguments = { typeArgument };
                Type newType = genericType.MakeGenericType(typeArguments);
                object createdTypeListFaculty = Activator.CreateInstance(newType);
                Console.WriteLine(createdTypeListFaculty.GetType().ToString());
                Console.Read();
            }
    
        }
        public class Faculty
        {
            public string Test = "Hello";
        }
    }

    • Помечено в качестве ответа Artemy.Sh 20 марта 2012 г. 11:19
    20 марта 2012 г. 6:03
    Модератор
  • Спасибо, а как сейчас с createdTypeListFaculty работать как с листом?
    20 марта 2012 г. 8:42
  • Самый лёгкий способ это, вместо:

    object createdTypeListFaculty = Activator.CreateInstance(newType);
    объявить так:

    dynamic createdTypeListFaculty = Activator.CreateInstance(newType);
    А потом работаете с этой переменной так как обычно, просто IntelliSense в Visual Studio не будет работать.

    • Помечено в качестве ответа Artemy.Sh 20 марта 2012 г. 11:19
    20 марта 2012 г. 10:27
    Модератор
  • А других способов нет? Просто данный способ работает только начиная с Framework 4.
    20 марта 2012 г. 10:52
  • А у Вас не .Net 4? Если без dynamic, то придётся писать приличное количество кода, опять таки через рефлексию. Вот чтобы не писать много и придумали dynamic,для подобных случаев как Ваш.
    20 марта 2012 г. 11:00
    Модератор
  • Просто требования такие к проекту, спасибо большое за помощь
    20 марта 2012 г. 11:18
  • > как мне передать на сервер тип, к которому приводить данные?
     
     
    как вариант: добавить в тело POST-запроса название типа. на сервере прочесть название и выполнить десериализацию данных. см. здесь
     
     
    21 марта 2012 г. 6:50