【问题标题】:Accessing a Method of a Class within a WCF Service from the Client从客户端访问 WCF 服务中的类的方法
【发布时间】:2015-11-09 21:42:03
【问题描述】:

我有这种情况,我有一个基类 Book,它有两个子 FictionBook 和 NonFictionBook,它们都覆盖了 ToString 方法。目前,这些类位于 WCF 服务解决方案中,并且我在客户端上获得了图书列表 (List),但是,在尝试使用子类的 .ToString() 方法时,我被卡住了。

这是来自客户端的代码:

        BookServiceClient bookService = new BookServiceClient("BasicHttpBinding_IBookService");

        List<Book> matchingBooks = new List<Book>();
        matchingBooks = (bookService.SearchBookByTitle(upperBookTitle)).ToList();

        if (matchingBooks.Count > 0)
        {
            int count = 1;
            foreach (Book book in matchingBooks)
            {
                Console.WriteLine("Matching Book " + count + ": " + book.ToString());
                count++;
            }
        } else
        {
            Console.WriteLine("No matching books found");
        }

这是服务中覆盖 ToString 方法的子类之一。另一个子类 NonFictionBook 也覆盖了 ToString 方法,需要从客户端访问:

 namespace BookModels
 {
    [DataContract]
    class FictionBook : Book
    {
       [OperationContract]
       public override string ToString()
       {
          return string.Format("Title: {0}, ISBN: {1}, Author: {2}", title, isbn, author);
       }
    }
 }

因此,简而言之,我想从调用服务的客户端访问 ToString 方法。

实现这一目标的最佳解决方案是什么?

【问题讨论】:

  • 在 Book 类中,你是否使用 virtual 或 abstract 来覆盖 .ToString()?
  • @JoseM - Book 类是一个抽象类
  • WCF 生成一个代理类,允许您访问属性,但我不确定它是否对方法执行相同操作。
  • 也许这更能说明这个问题。 link1link2
  • 按照设计,DataContracts 没有方法。它们是一个将数据序列化以通过网络传输的容器。这是 SOA 的事情——没有办法(在 SOA 的概念内)告诉客户如何实现一个方法。使其工作的唯一方法是将 DataContracts 移动到服务和客户端共享的单独程序集中。然后您可以使用 DataContract 中的方法,尽管这通常不是最佳实践。

标签: c# wcf


【解决方案1】:

从您的 WCF 服务中取出模型.....让您的应用程序和 WCF 服务继承 Book 类所在的库。以这种方式使用它。

【讨论】:

    【解决方案2】:

    1.正如 TheGeekYouNeed 所说,您需要共享一个库

    在客户端和服务器之间。

    2。但是你还需要在基类上设置多态性

    否则你会得到CommunicationException

    设置多态性,以便可以序列化派生类型。
    这意味着可以序列化的派生类在基类上声明。

    [DataContract]
    [KnownType(typeof(FictionBook))]
    [KnownType(typeof(NonFictionBook))]
    public abstract class Book
    

    3.然后你就可以用ChannelFactory&lt;T&gt;的服务器了

     IBookService client = ChannelFactory<IBookService>.CreateChannel( 
         new BasicHttpBinding(),
         new EndpointAddress("http://localhost:8733/Design_Time_Addresses/BookService/")
     );
     List<Book> books = client.GetBooks();
     foreach (var book in books)
         Console.WriteLine(book);
    

    您可以这样做,因为服务器和客户端共享一个可以放置接口的库。
    好的,在“不是 SOA”之间共享一个库。
    但它的好处是当接口改变时,在未改变的那一侧(客户端或服务端)会出现编译错误。
    [在理想世界中还可以——接口应该是不可变的;-)]

    问候

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-01-12
      • 2011-11-10
      • 2011-06-26
      • 1970-01-01
      相关资源
      最近更新 更多