6

以下の例を確認してください

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にはsubtract()メソッドがあり、Itest2にはadd()メソッドがあります。

両方とも、G と呼ばれる 1 つの具象クラスによって実装されます。

WCF を介して ITest を公開するだけの場合は、次のエンドポイント構成があります。

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

このサービスを実行して wsdl を確認すると、itest2 にあるメソッドが wsdl にも表示されていることがわかります。この例では、subtract() メソッドのみを公開する必要があります。しかし add() メソッドも公開されています。

私の要件は、ITest インターフェイスのメソッドを公開することだけです。この場合、ITestで宣言されているsubtract()メソッドのみを公開したいと思います。しかし、それらの実装は両方とも、1 つの具象クラス「G」のみに存在します。ここで何が欠けていますか?

編集: Service.svc ファイルの内容を指定しました:

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

ここに画像の説明を入力

4

2 に答える 2

4

構成内の要素のname属性の値が、サービス クラスの完全修飾名であることを確認してください。構成では、名前空間 (GServices.itest) で修飾されたエンドポイント コントラクト名がありますが、サービスは (GQS1) ではありません。特定のサービスのサービス構成がない場合、WCF は、問題を明らかにする既定のエンドポイントを 1 つ追加します。たとえば、次のコードでは、1 つのエンドポイントを追加する行がコメント アウトされていますが、サービスの WSDL は両方の操作を示しています。ただし、この行のコメントを外すと (サービスに ITest タイプのエンドポイントが 1 つだけ含まれるようになります)、「減算」操作のみが表示されます。<service>

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();
    }
}
于 2012-07-05T14:39:39.403 に答える
1

インターフェイスをサービスとして公開する必要がない場合は、インターフェイスから属性をITest2削除するだけです。ServiceContract

別のサービスが必要な場合ITest2は、インターフェイスの継承を使用してこの問題を解決できます。

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

[ServiceContract]
interface ITest2Service : ITest2 { }

ITest2最初のサービス(これも実装しますITest)と2番目のサービスで使用しITest2Serviceます。

于 2012-07-05T07:58:59.800 に答える