0

I have this scenario, where I have a base class Book, which has two children FictionBook and NonFictionBook, both of which are overriding the ToString method. Currently, these classes are within a WCF Service Solution and I am getting a List of Books (List) on the client, however, I am stuck when attempting to utilise the .ToString() method of the child classes.

This is the code from the Client:

        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");
        }

This is one of the child classes within the Service which has overridden the ToString method. The other child class NonFictionBook is also overriding the ToString method and needs to be accessible from the client:

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

Therefore, in a nutshell, I would like to access the ToString method from the client which is calling the Service.

What is the best solution to achieve this?

Ryan S
  • 3,210
  • 17
  • 48
  • 79
  • in the Book class, did u use virtual or abstract to override .ToString()? – mugabits Nov 09 '15 at 21:47
  • @JoseM - The Book Class is an Abstract class – Ryan S Nov 09 '15 at 21:52
  • WCF generates a proxy class that allows you to have access to the properties, but I'm unsure if it does the same for the methods. – mugabits Nov 09 '15 at 22:06
  • Maybe this shine more light on this issue. [link1](http://stackoverflow.com/questions/1181039/wcf-datacontract-tostring-function) [link2](http://stackoverflow.com/questions/10850111/override-tostring-method-in-wcf-service) – mugabits Nov 09 '15 at 22:09
  • 1
    By design, DataContracts don't have methods. They're a container that serializes data for transmitting over the wire. This is an SOA thing - there's no way (within the concept of SOA) to tell a client how to implement a method. The only way to get this to work is if you move the DataContracts into a separate assembly that is shared by both the service and the client. Then you can utilize methods in the DataContract, though this is not normally best practice. – Tim Nov 09 '15 at 23:50

2 Answers2

1

Take the models out of your WCF service ..... Have your application and WCF service inherit the library the Book class is in. Use it that way.

TheGeekYouNeed
  • 7,509
  • 2
  • 26
  • 43
0

1. As says TheGeekYouNeed, you need to share a Library

Between client and server.

2. But you also need to set polymorphism on the base class

Otherwise you 'll get a CommunicationException

Setting polymorphism so derived types can be serialized.
Here it means the derived classes that can be serialized are declared on the base class.

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

3. Then you can use the server with ChannelFactory<T>

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

And you can do it because server and client share a library where the interface can be put.
Ok sharing a library between "is not SOA".
But it has the advantage that when the interface is changed, there is a compile error on the unchanged side ( client or server).
[OK in an ideal world - interfaces should be immutable ;-) ]

Regards

Emmanuel DURIN
  • 4,803
  • 2
  • 28
  • 53