Ryan S
Ryan S

Reputation: 3268

Accessing a Method of a Class within a WCF Service from the Client

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?

Upvotes: 0

Views: 1259

Answers (2)

Emmanuel DURIN
Emmanuel DURIN

Reputation: 4913

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

Upvotes: 0

TheGeekYouNeed
TheGeekYouNeed

Reputation: 7539

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.

Upvotes: 1

Related Questions