【问题标题】:Is possible in WCF service: method return IList<object> when object can be Person class?WCF 服务中是否可能:当对象可以是 Person 类时,方法返回 IList<object>?
【发布时间】:2010-02-25 15:09:22
【问题描述】:

在 WCF 服务中是否可以:当对象可以是 Person 类时方法返回 IList?

例如:在 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:服务器没有提供有意义的回复;这可能是由合同不匹配、会话过早关闭或内部服务器错误引起的

【问题讨论】:

    标签: silverlight wcf service


    【解决方案1】:

    理论上是的,尽管您需要告诉服务它可能在您的方法中使用 KnownTypeAttribute 来告诉服务它可能需要一个 Person 对象。

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

    不过,在实践中我真的会三思而后行 - 而是为您期望返回的对象声明不同的方法签名:

    [OperationContract]
    IList<Person> GetPeople();
    
    [OperationContract]
    Person GetPerson();
    
    [OperationContract]
    IList<Book> GetBooks();
    
    [OperationContract]
    Book GetBook();
    

    等等

    它应该是一个合同,即具体的,所以如果你突然改变你返回的类的类型,它真的会把客户搞得一团糟。

    在您的示例中,您还返回了一个具体的 List 类 - 应该避免这种情况,而是使用 IList&lt;&gt;Collection&lt;&gt;

    【讨论】:

    • 好的。但是当:返回null;或 IList a = null;返回空值;问题不存在。真的有必要为每个类实现一个方法吗?我有 50 个表和 50 个类 DTO 映射。那么,我需要 50 种方法吗?我尝试制作 RIA silverlight 应用程序。对不起,我的英语不好。您的评论对我帮助很大。
    • 问题是 WCF 认为它正在获取一个对象,而实际上它正在获取一个 Person,并且它对 Person 一无所知。当你返回null时,它知道null,所以没关系。将 KnownType 属性添加到您的方法和 Person 类的 [DataContract] 中。相信我 - 这将有助于分离您的方法,并且对于其他人(和您自己)阅读您的代码以确切地了解您得到什么会更有意义。
    【解决方案2】:
    1. 是的,有可能,您需要更新 Visual Studio 中的引用(或用于生成代理类的任何内容)并更改返回的集合类型。 “配置服务参考”中有一个选项,您可以在其中选择 Generic.List(右键单击您的 WCF 服务参考)。
    2. 不匹配是因为您在服务器端更改了服务并且没有获得新的代理。因此,将其更改为返回一个 Generic.List,然后使用 1 中的步骤重新生成。

    希望有帮助

    瑞恩

    【讨论】:

      【解决方案3】:

      您可以返回 IList,但这绝对不是一个好方法。

      当你公开你的服务时,你需要服务另一端的人知道他们得到了什么。

      IList&lt;Person&gt; 对于使用服务或服务中的代码的每个人来说都会更清楚。

      如果您需要一个可以返回不同类型对象的方法,只需将它们拆分为多个操作即可。

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

      我的 2 美分。

      【讨论】:

      • 好的,但是,当我知道一组类(如人、动物、客户等)并需要填写 IList 时?这是同样的任务,一次又一次。一种填充实体列表的方法非常错误吗?我同意你的意见。因此,一切都更加结构化和清晰。但是,通过类名或类类型,我获得表名并通过 ado.net 访问 BD 和 DataReader,然后我可以使用唯一的方法。有这么错吗?感谢您的意见。
      【解决方案4】:

      Cheva(等人),

      没有什么能阻止您调用单个方法来填充您从服务调用返回的集合。

      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。 ; )

      -斯科特

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-04-26
        • 2020-04-10
        • 1970-01-01
        相关资源
        最近更新 更多