Xeun
Xeun

Reputation: 1119

Generic Interface in hierachy in ServiceContract

I've got a generic interface:

[ServiceContract]
public interface IGenericDataRepository<T> where T : class
{
    [OperationContract]
    IList<T> GetAll(params Expression<Func<T, object>>[] navigationProperties);

    [OperationContract]
    IList<T> GetList(Func<T, bool> where, params Expression<Func<T, object>>[] navigationProperties);

    [OperationContract]
    T GetSingle(Func<T, bool> where, params Expression<Func<T, object>>[] navigationProperties);

    [OperationContract]
    void Add(params T[] items);

    [OperationContract]
    void Update(params T[] items);

    [OperationContract]
    void Remove(params T[] items);
}

Which should be used within a WCF Service, like so:

[ServiceContract]
public interface ICustomerService : IGenericDataRepository<Customer>
{
    [OperationContract]
    Customer GetCustomers();
}

The service gets exposed via the following lines of code:

Uri baseHttpAddress = new Uri("http://localhost:9999/CustomerService");
ServiceHost customerServiceHost = new ServiceHost(typeof(CustomerService), baseHttpAddress);
customerServiceHost.AddServiceEndpoint(typeof(ICustomerService), new WSHttpBinding(), "");

 ServiceMetadataBehavior serviceMetadataBehavior = new ServiceMetadataBehavior { HttpGetEnabled = true };
 ServiceDebugBehavior serviceDebugBehavior = new ServiceDebugBehavior { IncludeExceptionDetailInFaults = true};    customerServiceHost.Description.Behaviors.Add(serviceMetadataBehavior);

  customerServiceHost.Open();

However, this does not seem to work. Is it not possible to have a generic interface in the hierachy of the ServiceConrtacts? I was not able to find some information about it.

The problem is I am not able to connect to the Service when I want to add it as Service Reference - by using the WCF TestClient i get the following exception:

Error: Cannot obtain Metadata from http://localhost:9999/CustomerService If this is a Windows (R) Communication Foundation service to which you have access, please check that you have enabled metadata publishing at the specified address.  For help enabling metadata publishing, please refer to the MSDN documentation at http://go.microsoft.com/fwlink/?LinkId=65455.WS-Metadata Exchange Error    URI: http://localhost:9999/CustomerService    Metadata contains a reference that cannot be resolved: 'http://localhost:9999/CustomerService'.    <?xml version="1.0" encoding="utf-16"?><Fault xmlns="http://www.w3.org/2003/05/soap-envelope"><Code><Value>Sender</Value><Subcode><Value xmlns:a="http://schemas.xmlsoap.org/ws/2005/02/sc">a:BadContextToken</Value></Subcode></Code><Reason><Text xml:lang="de-DE">The message could not be processed. This is most likely because the action 'http://schemas.xmlsoap.org/ws/2004/09/transfer/Get' is incorrect or because the message contains an invalid or expired security context token or because there is a mismatch between bindings. The security context token would be invalid if the service aborted the channel due to inactivity. To prevent the service from aborting idle sessions prematurely increase the Receive timeout on the service endpoint's binding.</Text></Reason></Fault>HTTP GET Error    URI: http://localhost:9999/CustomerService    There was an error downloading 'http://localhost:9999/CustomerService'.    The request failed with the error message:--<HTML><HEAD><STYLE type="text/css">#content{ FONT-SIZE: 0.7em; PADDING-BOTTOM: 2em; MARGIN-LEFT: 30px}BODY{MARGIN-TOP: 0px; MARGIN-LEFT: 0px; COLOR: #000000; FONT-FAMILY: Verdana; BACKGROUND-COLOR: white}P{MARGIN-TOP: 0px; MARGIN-BOTTOM: 12px; COLOR: #000000; FONT-FAMILY: Verdana}PRE{BORDER-RIGHT: #f0f0e0 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #f0f0e0 1px solid; MARGIN-TOP: -5px; PADDING-LEFT: 5px; FONT-SIZE: 1.2em; PADDING-BOTTOM: 5px; BORDER-LEFT: #f0f0e0 1px solid; PADDING-TOP: 5px; BORDER-BOTTOM: #f0f0e0 1px solid; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e5e5cc}.heading1{MARGIN-TOP: 0px; PADDING-LEFT: 15px; FONT-WEIGHT: normal; FONT-SIZE: 26px; MARGIN-BOTTOM: 0px; PADDING-BOTTOM: 3px; MARGIN-LEFT: -30px; WIDTH: 100%; COLOR: #ffffff; PADDING-TOP: 10px; FONT-FAMILY: Tahoma; BACKGROUND-COLOR: #003366}.intro{MARGIN-LEFT: -15px}</STYLE><TITLE>Service</TITLE></HEAD><BODY><DIV id="content"><P class="heading1">Service</P><BR/><P class="intro">The server was unable to process the request due to an internal error.  For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.</P></DIV></BODY></HTML>--.

Thank you very much!

Upvotes: 1

Views: 147

Answers (2)

David Basarab
David Basarab

Reputation: 73351

You can't really use generics with WCF. The primary reason is because WCF is to exchange messages.

Now you can use a base object with a known type, rather than T.

You also cannot pass function pointers through a service since they cannot serialize. Remember a rule of thumb with serialization is that the implementation has to be concrete.

[DataContract]
[KnownType(typeOf(Customer)]
public abstract class GenericType
{
}

[DataContract]
public class Customer : GenericType
{
}

Now I would rethink your design. Remember WCF is a service you and need to treat it as such. The interface you have feels to me like something that would talk directly to a data store. You might need a layer ahead of it.

Upvotes: 2

hvojdani
hvojdani

Reputation: 470

error

"Metadata contains a reference that cannot be resolved"

root clause is System.Linq.Expressions.Expression class is not Serializable. will work if you remove those methods that have Func and Expression parameters.

you must implement your own query class or use wcf data services

Upvotes: 1

Related Questions