Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Two Interface and one concrete class in WCF

please check the below example

namespace GServices
{
    [ServiceKnownType(typeof(SearchType))]
    [ServiceContract(SessionMode = SessionMode.Allowed)]
    public interface ITest
    {
        [OperationContract]
        int subtract(int x, int y);
    }

    [ServiceKnownType(typeof(SearchType))]
    [ServiceContract(SessionMode = SessionMode.Allowed)]
    public interface ITest2
    {
        [OperationContract]
        int add(int x, int y);

    }
    public class G : ITest2, ITest
    {
        public int add(int x, int y)
        {
            return x + y;
        }
        public int subtract(int x, int y)
        {
            return x + y;
        }
    }
}

ITest has subtract() method and Itest2 has add() method.

Both are implemented by one concrete class called G.

If i just want to expose the ITest through WCF, I have following endpoint config

  <service name="GQS1" behaviorConfiguration="GQwcfBehaviour">
    <endpoint address="DP2Svcs" binding="wsHttpContextBinding" bindingConfiguration="wsHttpEndpointBindingConfig" contract="GServices.itest">
      <identity>
        <dns value="localhost" />
      </identity>
    </endpoint>
  </service>

when i run this service and check the wsdl, I can see that the methods which are in itest2 also appeared in wsdl. in this example case , subtract() method should only be exposed. But add() method is also exposed.

My requirement is to have methods in ITest Interface should only exposed. in this case , i want to expose only subtract() method which is declared in ITest. But both of their implementation resides in Only one concrete class "G". What am I missing here?

Edit : I have given my Service.svc file content :

<%@ ServiceHost Language="C#" Debug="true" Service="GServices.G"  %>

enter image description here

like image 274
amaz Avatar asked Jul 05 '12 07:07

amaz


2 Answers

Make sure that the value of the name attribute in the <service> element in the configuration is the fully-qualified name of the service class. In your config you have the endpoint contract name qualified by a namespace (GServices.itest), but the service is not (GQS1). If you don't have any service confugration for a specific service, WCF will add one default endpoint which wil expose the problem you have. For example, in the code below, where the line which adds one endpoint is commented out, the WSDL on the service shows both operations. But if you uncomment the line (which will make the service have only one endpoint of type ITest), only the "subtract" operation will be shown.

public class StackOverflow_11339853
{
    [ServiceContract(SessionMode = SessionMode.Allowed)]
    public interface ITest
    {
        [OperationContract]
        int subtract(int x, int y);
    }

    [ServiceContract(SessionMode = SessionMode.Allowed)]
    public interface ITest2
    {
        [OperationContract]
        int add(int x, int y);

    }
    public class G : ITest2, ITest
    {
        public int add(int x, int y)
        {
            return x + y;
        }
        public int subtract(int x, int y)
        {
            return x + y;
        }
    }
    public static void Test()
    {
        string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
        ServiceHost host = new ServiceHost(typeof(G), new Uri(baseAddress));
        // host.AddServiceEndpoint(typeof(ITest), new BasicHttpBinding(), "");
        host.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true });
        host.Open();
        Console.WriteLine("Host opened");

        Console.Write("Press ENTER to close the host");
        Console.ReadLine();
        host.Close();
    }
}
like image 164
carlosfigueira Avatar answered Oct 21 '22 07:10

carlosfigueira


If you don't need the ITest2 interface exposed as a service, simply remove the ServiceContract attribute from it.

If you need ITest2 in a different service, you can use interface inheritance to solve this issue:

interface ITest2
{ 
    [OperationContract]
    int Add(int x, int y);
}

[ServiceContract]
interface ITest2Service : ITest2 { }

Use ITest2 in the first service (that also implements ITest) and ITest2Service in the second service.

like image 36
Eli Arbel Avatar answered Oct 21 '22 07:10

Eli Arbel