【问题标题】:WCF passing a custom object to client and running its methodsWCF 将自定义对象传递给客户端并运行其方法
【发布时间】:2018-08-13 09:25:16
【问题描述】:

这既是一个设计问题,也是一个技术问题。我不确定我这样做是否正确......

我有一个 WCF API,它与 DB 通信并传回一个 Person 对象(在单独的 .dll 中定义)它具有方法和属性。对象正从 WCF 发送到调用客户端。

我想在客户端调用 Person 的方法。我知道这些不能从 API 向下游发送。但是,如果我引用 WCF 使用的同一个 .dll,我应该能够将 API Person 转换为 .dll Person 然后运行这些方法吗?

我希望很清楚我想要达到的目标。

【问题讨论】:

    标签: c# wcf


    【解决方案1】:

    WCF 通过数据契约工作。这些是要返回的数据模型,例如带有属性的Person 对象。在将对象从 Service 传输到 Client 的过程中,不必担心方法。如果使用数据协定,并且您将引用 WCF,则代理类将生成一个 Person 对象。

    如果您的逻辑更复杂,我想这取决于您的情况。让我用几句话来描述:

    1. 如果不能更改类的源,又想调用公共方法,最好使用反射。因此,您从 WCF 接收一个对象,使用返回的值设置 Person 对象的属性,然后调用该方法。

    2. 如果你可以改变类的来源,你可以创建一个基接口IPerson,用类中Person对象的属性实现这个接口,并返回一个IPerson对象。在这种情况下,您将能够执行演员阵容。

    更多详情: 好的,让我为您提供更多详细信息:

    1. 作为最佳实践,我建议使用接口创建单独的类。这应该是一个描述您的对象的数据合约接口。像这样的:

      [DataContract] 
      public interface IPerson
      {
         [DataMember]
         public int Identifier { get; set; }
      
         [DataMember]
         public string First { get; set; }
      
         [DataMember]
         public string Last { get; set; }
      
         public string GetSomething();
      }
      
    2. 您正在实施的 WCF 上的方法应返回 IPerson 类型。

    3. 在共享类中,请为您的Person 对象实现接口IPerson
    4. 在您的服务和客户端项目中引用此程序集。
    5. 在您的客户端项目中添加对 WCF 服务的 Web 引用。
    6. 您的方法将返回 IPerson 类型的对象,因此您可以使用共享库中的 Person 对象,并使用其所有方法。

    【讨论】:

    • 感谢您的快速回复,外部 dll 是我自己的,所以我可以修改源代码,您能否详细解释一下选项 2。我喜欢这个概念但不完全理解。跨度>
    • 那么你有一个包含数据合约接口的dll,还有一个包含这些接口实现的共享dll?我应该从 WCF 服务项目和客户端项目中引用这两个 dll 吗?那么实现单独的interfaces dll有什么用呢?
    • 我收到投诉称“[DataContract]”对接口无效
    【解决方案2】:

    WCF 支持重用已包含在项目中的引用的能力。从这个意义上说,您可以创建一个合同程序集(一个包含您的瘦域模型(例如Person 等)的程序集,您可以将自己的逻辑添加到其中。

    然后您可以将程序集添加到您的 WCF 服务和调用客户端项目,并指示 WCF 重新使用任何现有引用。这样,从您的服务中提取的内容被反序列化为 Person 的本地副本,而不是作为代理生成的 Person,您实际上获得了一个完整的实例,您可以在其上执行方法调用。

    别忘了,在这种情况下,您是按价值编组的。您对 Person 实例所做的任何更改仅对客户端而言是本地的,您需要再次将其传递回上游(通过序列化),以便服务识别任何更改并采取相应措施。

    【讨论】:

    • 有更好的方法吗?在服务器和客户端上创建一个 Person 对象可能吗?我认为这样我只需要创建一个 Person 对象加上其他几个可以在服务和客户端之间共享的对象。我正在寻找最优雅的解决方案,这是我正在从事的个人项目。
    • 我认为你没有抓住重点。您只需执行一次Person。在共享程序集(合同程序集)中。然后在服务和客户端上引用它。
    • 不,我明白,截至 15 分钟前有一个可行的解决方案。谢谢!但是,这是在共享程序集中执行此操作的最佳方式吗?我是 WCF 的新手。你预见到它有什么问题吗?
    • 嗯,这确实是你唯一能做的。 [DataContract] 不支持方法调用,所以从这个意义上说,在多个项目之间共享程序集不是一个坏主意。
    【解决方案3】:

    由于您引用的是同一个 dll,并且 WCF 可以是强类型的,因此您应该能够在不强制转换的情况下调用 Person 响应对象上的方法。确保在定义 Person 类时使用 DataContract 属性。

    在以下示例中,Person 类将由 WCF 序列化,其中包含服务器端的三个数据成员。客户端 WCF 将反序列化响应...创建类 Person。因此,在客户端,您可以调用 FullName() 并且无需强制转换即可工作。

     [DataContract]
     public class Person
    {
       [DataMember]
       public int Identifier { get; set; }
       [DataMember]
       public string First { get; set; }
       [DataMember]
       public string Last { get; set; }
       public string FullName()
       {
          return First + " " + Last;
       }  
    }
    

    【讨论】:

    • 这就是我的对象的外观,我可以在客户端查看 int,first 和 last 但看不到方法... pService.Person p = API.GetPerson(123);
    • 该方法的范围是否为 Public?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多