0

IISでホストされている2つのエンドポイント(1つのwebHttpBindingと1つのbasicHttpBinding)を持つWCFサービスがあります。クライアントは問題なくhttpリクエストを行うことができます。WCFTestClientを介してSOAPエンドポイントに接続して呼び出しを行うことができ、クライアントプロジェクトにサービス参照を正常に追加することができました。問題は、クライアントのReference.csファイルまたはapp.configファイルにコードが生成されていないことです...どちらも空です。

私の質問は、なぜWCFTestClientを介して問題なくSOAPエンドポイントに接続して呼び出しを行うことができるのに、AddServiceReferenceメソッドを介してはできないのでしょうか。

編集:サービス参照を追加しているアセンブリにある参照に問題があるようです。別のクラスライブラリ(同じライブラリがサービスに存在します)を参照していますが、ソリューションをビルドすると次の警告が表示されます。

Warning 12  Custom tool warning: Cannot import wsdl:portType
Detail: An exception was thrown while running a WSDL import extension: System.ServiceModel.Description.DataContractSerializerMessageContractImporter
Error: Referenced type 'MyNamespace.KPI.ChartObject`2, MyNamespace.KPI.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3e720b7e8a51f8d5' with data contract name 'ChartObjectOfdecimalZKPIPeriodaU4eboDJ' in namespace 'http://schemas.datacontract.org/2004/07/MyNamespace.KPI' cannot be used since it does not match imported DataContract. Need to exclude this type from referenced types.

この特定のクラスはジェネリッククラスであることに注意してください...これがエラーと関係があるかどうかはわかりません。

4

2 に答える 2

1

あなたはあなたのABCに従う必要があります:

  • 住所
  • バインディング
  • 契約

HTTPを介して公開されるアドレスには、デプロイメントURLが必要です。どのインターネット情報システムがあなたのためにそれらすべてを処理していますか。でも; 適切な定義なしでを使用しようとするService Referenceと、表示されません。それがどこに向かっているのか詳細がないので

その基準を定義すると、通常どおりに表示されます。


アップデート:

同じサービスコントラクトからSOAPとRESTをまとめることも、それらを分離することもできます。この例では、それらを分離します。

サービスを作成します。

[ServiceContract]
public interface IMath
{
      [OperationContract]
      int Add(int Number1, int Number2);
}

休息のためのサービス契約を作成します。

[ServiceContract]
public interface IMathRest
{

     [OperationContract]
     [WebGet(UriTemplate = "/Add/{Number1}/{Number2}", RequestFormat = WebMessageFormat.Json,
              ResponseFormat = WebMessageFormat.Json)]
     int AddRest(string Number1, string Number2);
}

上記のサービスでは; メッセージ形式を明示的に設定しています。

サービスの実装:「バインディング」

public class Math : IMath, IMathRest
{
     public int Add(int Number1, int Number2)
     {
         return Number1 + Number2;
     }

     public int AddRest(string Number1, string Number2)
     {
         int num1 = Convert.ToInt32(Number1);
         int num2 = Convert.ToInt32(Number2);
         return num1 + num2;
     }
}

サービスを構成します。

<serviceBehaviors>
      <behavior name = "servicebehavior">
          <serviceMetadata httpGetEnabled = "true" />
          <serviceDebug includeExceptionDetailInFaults = "false" />
      </behavior>
</serviceBehaviors>

上記は、サービスをBasic /WebHttpに設定します。

を構成した後serviceBehavior、エンドポイントを定義する必要があります。

<endpointBehaviors>
     <behavior name="restBehavior">
          <webHttp/>
     </behavior>
</endpointBehaviors>

これにより、RESTエンドポイントがwebHttpBinding上記で指定されたものに構成されます。次に、石鹸を定義する必要があります。

<endpoint name = "SoapEndPoint"
       contract = "Namespace in which Service Resides goes here"
       binding = "basicHttpBinding" <!-- Mirrors are above configuration -->
       address = "soap" />

上記はあなたの構成に入ります。ただし、サービスの利用時には、エンドポイント名が必要です。エンドポイントは、ベースアドレス/ソープアドレスで利用できます。使用するバインディングが指定されています。

残りの部分ではなく、石鹸のみを構成したことを除いて。したがって、エンドポイントを指定する必要があります。

<endpoint name = "RestEndPoint"
       contract = "Namespace that our Rest Interface is located goes here"
       binding = "webHttpBinding"
       address = "rest"
       behaviorCOnfiguration = "restBehavior" />

レストエンドポイントは、URL(ベースアドレス/レスト/追加/パラメーター/パラメーター)で呼び出されます。バインドを指定しました。休息行動を設定します。

すべてをまとめると、次のようになります。

<?xml version="1.0"?>
<configuration>
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>
  <system.serviceModel>
    <behaviors>
      <serviceBehaviors>
        <behavior name ="servicebehavior">        
          <serviceMetadata httpGetEnabled="true"/>        
          <serviceDebug includeExceptionDetailInFaults="false"/>
        </behavior>
      </serviceBehaviors>
      <endpointBehaviors>
        <behavior name="restbehavior">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
    <services>
      <service name ="MultipleBindingWCF.Service1"
               behaviorConfiguration ="servicebehavior" >
        <endpoint name ="SOAPEndPoint"
                  contract ="MultipleBindingWCF.IService1"
                  binding ="basicHttpBinding"
                  address ="soap" />

        <endpoint name ="RESTEndPoint"
                  contract ="MultipleBindingWCF.IService2"
                  binding ="webHttpBinding"
                  address ="rest"
                  behaviorConfiguration ="restbehavior"/>

        <endpoint contract="IMetadataExchange"
                  binding="mexHttpBinding"
                  address="mex" />
      </service>
    </services>   
  </system.serviceModel>
 <system.webServer>
    <modules runAllManagedModulesForAllRequests="true"/>
  </system.webServer> 
</configuration>

消費する:

私たちの石鹸を消費するのは簡単です。まっすぐ進む。サービスリファレンスを作成し、電話をかけます。

static void CallingSoapFunction()
{
     SoapClient proxy = new SoapClient("SoapEndPoint");
     var result = proxy.Add(7,2); // Proxy opens the channel, we invoke our method, we input our parameters.
     Console.WriteLine(result);
}

安らかな消費を除いて、わずかに異なります。特に、Jsonにフォーマットする必要があるためです。したがって、名前を正確に指定する必要があります。

Restは、データの逆シリアル化をJsonに依存します。

static void CallRestFunc()
{
     WebClient RestProxy = new WebClient();
     byte[] data = RestProxy.DownloadData(new Uri("http://localhost:30576/MathRest.svc/Rest/Add/7/2")); // As you see it is following the exact location of the project, invoking method / parameter and so on down the line.
Stream stream = new MemoryStream(data);
DataContractJsonSerializer obj = new DataContractJsonSerializer(typeof(string));
string result = obj.ReadObject(stream).ToString();
Console.WriteLine(result);
}

上記は、RestUriを使用してデータをダウンロードします。そのデータを逆シリアル化します。表示されます。

うまくいけば、それは明確にするのに役立ちます。

適切なアイテムが構成ファイルに作成されていない場合。そうすると、適切な消費ができなくなります。ABCはWCFで重要です。構成ファイルに作成されていない場合は、プログラムでコードに作成する必要があります。


アップデート:

static void Main(string[] args)
{
    var binding = new BasicHttpBinding();
    var endpoint = new EndpointAddress("http://localhost:8080/");
    using (var factory = new ChannelFactory<IPerson>(binding, endpoint))
    {
        var request = new Dictionary<Guid, Person>();
        request[Guid.NewGuid()] = new Person { Name = "Bob", Email = "Bob@abc.com" };

        var client = factory.CreateChannel();
        var result = client.SetCustomer(request);

        Console.WriteLine("Name: {0} | Email: {1}", result.Name, result.Email);
        factory.Close();
    }
    Console.ReadKey(true);
}

この基本的な例でわかるように、バインディングとエンドポイントの両方が構成されています。これらすべてがサーバーとクライアントの両方で定義されていることを確認する必要があります。それがどこに向かっているのかを知る必要があります。それはもっと理にかなっていますか?

于 2013-01-04T00:10:22.753 に答える
0

このURLをチェックしてください。これがお役に立てば幸いです。

于 2013-11-11T10:03:37.423 に答える