4

I have a Generic Service Interface:

[ServiceContract]
public interface IService<T> where T : Class1
{
    [OperationContract]
    void DoWork(T class1);
}

Then I have a Concrete Service that inherits from that:

public class Service : IService<Class1>
{
    public void DoWork(Class1 class1)
    {
    }
}

Everything works fine until I add a webHttpEndpoint to expose a JSON WS:

<service name="Service">
    <endpoint 
        address="" 
        binding="webHttpBinding" 
        behaviorConfiguration="webHttpBehavior"
        contract="IService"  />
</service>

<behavior name="webHttpBehavior">
    <enableWebScript />
</behavior>

In fact, I receive this error:

The contract name 'IService' could not be found in the list of contracts implemented by the service 'Service'.

That's beacuse of the generic definition of the interface. Any solution?

user758977
  • 431
  • 1
  • 7
  • 19

3 Answers3

3

In my opinion (and based on what you said), the interface does not need to be generic. The caller just need to know that there is a DoWork operation.

So basically, change the concrete class to be generic instead of the interface.

public class Service<T> : IService where T : Class1
{
    public void DoWork()
    {
    }
}

EDIT after clarifying the question: You need to provide the generic parameter in the config file as well:

contract="YourAssembly.IService`1[[YourAssembly.Class1, YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]"

Here is a similar question: Inheriting from a generic contract in WCF

Community
  • 1
  • 1
Johann Blais
  • 9,389
  • 6
  • 45
  • 65
  • Thanks again. My contract looks like this now: contract="WebApplication1.IService`1[[WebApplication1.Class1, WebApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]" but it does not work. – user758977 Jun 03 '11 at 09:51
2

You must correctly write the type name of your contract into configuration. IService is not the name of IService<Class1>!!!

The configuration should look like:

<service name="Service">
    <endpoint 
        address="" 
        binding="webHttpBinding" 
        behaviorConfiguration="webHttpBehavior"
        contract="IService`1[Class1]"  />
</service>

<behavior name="webHttpBehavior">
    <enableWebScript />
</behavior>

Be aware that if your contract or service lives in any namespace, namespaces should be included in configuration.

Or in case of full names needed:

<service name="Namespace.Service, AssemblyName">
    <endpoint 
        address="" 
        binding="webHttpBinding" 
        behaviorConfiguration="webHttpBehavior"
        contract="Namespace.IService`1[[Namespace.Class1, AssemblyName]], AssemblyName"  />
</service>

<behavior name="webHttpBehavior">
    <enableWebScript />
</behavior> 
Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
0

Where is your Class1.....Instead of specifying any specific class make it a reference type using class

Try something this...

 [ServiceContract]public interface IService<T> where T : class
    { 
       [OperationContract] 
       void DoWork();
    }
Misam
  • 4,320
  • 2
  • 25
  • 43