Возможно в сервисе WCF: метод return IList <object>, когда объект может быть классом Person? - PullRequest
2 голосов
/ 25 февраля 2010

Возможно в службе WCF: метод, возвращающий IList, когда объектом может быть класс Person?

Пример: в IServiceContract.cs

[ServiceContract]
public interface IDAS
{
    [OperationContract]
    void DoWork();

    [OperationContract]
    List<object> GetAnyClass();

}

И класс:

public class DAS : IDAS
{
    public void DoWork()
    {
    }

    public List<object> GetAnyClass()
    {
        List<Person> a = new List<Person>();
        a.Add(new Person());
        return a;
    }
}

Проблема во время выполнения:

System.ServiceModel.CommunicationException: сервер не предоставил значимого ответа; это может быть вызвано несоответствием договора, преждевременным завершением сеанса или внутренней ошибкой сервера

Ответы [ 4 ]

1 голос
/ 25 февраля 2010

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

[OperationContract]
[KnownType(typeof(Person))]
List<object> GetAnyClass();

Я действительно дважды подумал бы о том, чтобы сделать это на практике - вместо этого объявлять разные сигнатуры методов для объектов, которые вы ожидаете вернуть:

[OperationContract]
IList<Person> GetPeople();

[OperationContract]
Person GetPerson();

[OperationContract]
IList<Book> GetBooks();

[OperationContract]
Book GetBook();

и т.д.

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

Также в вашем примере вы возвращали конкретный класс List - этого следует избегать, вместо этого используйте IList<> или Collection<>.

0 голосов
/ 12 октября 2010

Чева (и др.),

Ничто не мешает вам вызывать один метод, чтобы заполнить коллекцию (и), которую вы возвращаете после вызовов службы.

IList<Person> GetPersons(...)
IList<Animal> GetAnimals(...)

И GetPersons (), и GetAnimals () могут вызывать внутренний метод, например

  IList<Animal> GetAnimals(...)
  {
    // get list of objects of a given type
    internalIList<Object> genericResults = GetItems( 
        ItemType.Persons|ItemType.Animals );

    ...

    IList<Animal> results;

    // convert to specific type
    results = new IList<Animal>(genericResults);

    return results;
  }

Это должно сработать, но я не проверял это или что-то еще. YMMV. ; )

-Скотт

0 голосов
/ 25 февраля 2010

Вы можете вернуть IList, но это определенно не лучший подход.

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

IList<Person> будет понятнее для всех, кто использует службы или этот код в службах.

Если вам нужен метод, который может вернуть объект другого типа, просто разбейте их на несколько операций.

IList<Person> GetPersons(...)
IList<Animal> GetAnimals(...)

Мои 2 цента.

0 голосов
/ 25 февраля 2010
  1. Да, это возможно, вам нужно обновить ссылку в Visual Studio (или что бы вы ни использовали для создания прокси-класса) и изменить тип возвращаемой коллекции. В «Настроить ссылку на службу» есть опция, и вы можете выбрать там Generic.List (щелкните правой кнопкой мыши ссылку на службу WCF).
  2. Несоответствие связано с тем, что вы изменили службу на стороне сервера и не получили новый прокси. Поэтому измените его так, чтобы он возвращал Generic.List, а затем регенерируйте, используя шаги в 1.

Надеюсь, что поможет

Ryan

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...