2017-12-18 15 views
2

私がしたいのは、私は設定ファイルから "WSDL"サービスリンクを使用して、私が使用するメソッドの名前を取ってプログラムでプログラムを使用します。次のようにサービス参照とサービスを動的に作成する

コード私は静的に使用しているフラグメントおよびランニングは、

ServiceName.serviceClientSoapClient= new ServiceName.serviceClientSoapClient(); 

string xmlStr = client.getValues(); 

され、エンドポイントは、

<endpoint address="http://someservice.com/Service.asmx" 
     binding="basicHttpBinding" bindingConfiguration="serviceClientSoap" 
     contract="ServiceName.serviceClientSoap" name="serviceClientSoap" /> 

しかし、私はこのすべてをプログラムで作成したい、例えば です。

次に、この設定ファイルを使用して、サービスを使用して結果を取得します。

私は以下のリンクを見ましたが、ここでは1つのサービス構造によって行われています。私はそれを設定ファイルからインストールします。

How to programmatically connect a client to a WCF service? How to: Use the ChannelFactory

+0

ですかこれらのエンドポイントごとにインターフェースを用意しています(これらを設定したり、それらを識別する方法もあります)。または、応答の本文が文字列として返されると常に期待していますか? – rene

+0

xmlファイルを返します。 xmlファイルが到着したら、次のプロセスを動的に設定します。私はその時点で何の問題もありません。残念ながら、これらのエンドポイントのためのインタフェースはありません。私は実際の問題はとにかくここにいると思います。 @rene –

答えて

2

インターフェイスを作成し、それをサービスクライアントを実装するために良いかもしれません。このようにして、設定ファイルに必要なメソッドやパラメータなどを指定し、管理が難しくなっています。また、既知の型クラスとして結果オブジェクトを使用することはできません。

だから、あなたがそのような何か試すことができます:あなたが必要とするすべてのRequestReplyエンドポイントを処理するために、WCF CommunicationObjectある場合

var url = ConfigurationManager.AppSettings["serviceLink"]; 
var serviceClientClassName = ConfigurationManager.AppSettings["serviceClientClassName"]; 
var serviceMethod = ConfigurationManager.AppSettings["serviceMethod"]; 
var endpoint = new EndpointAddress(new Uri(url)); 
//Specify the assembly of services library. I am assuming that the services are stored in the Executing Assembly 
var serviceClient = Assembly.GetExecutingAssembly().GetTypes() 
    .FirstOrDefault(x => x.Name == serviceClientClassName);//Find the service client type 
var instance = Activator.CreateInstance(serviceClient); //Create a new instance of type 
var methodInfo = serviceClient.GetMethod(serviceMethod); //Get method info 
var result = methodInfo.Invoke(instance, new object[] {}); // Invoke it 
+0

今のところ、私は参照としてサービスを追加して実行します。しかし、実行時にサービスを追加できれば、すべてが動的になります。しかし、今のところあなたのソリューションは機能しています。 @レインマン –

0

を、以下の方法はあなたのためにそれを行います。

有効なリクエストメッセージとエンドポイントとsoapactionを受け取り、サービスによって返された未処理のxmlを返します。

Message何か他のものを与えたい場合は、ServiceContract属性とOperationContract属性で修飾されたIRequestChannelの代わりを実装する必要があります。

あなたが設定ファイルから2つのパラメータをフェッチする、または何らかの定数値を使用することができます上記の方法を使用するには

// give it a valid request message, endpoint and soapaction 
static string CallService(string xml, string endpoint, string soapaction) 
{ 
    string result = String.Empty; 

    var binding = new BasicHttpBinding(); 

    // create a factory for a given binding and endpoint 
    using (var client = new ChannelFactory<IRequestChannel>(binding, endpoint)) 
    { 
     var anyChannel = client.CreateChannel(); // Implements IRequestChannel 

     // create a soap message 
     var req = Message.CreateMessage(
      MessageVersion.Soap11, 
      soapaction, 
      XDocument.Parse(xml).CreateReader()); 

     // invoke the service 
     var response = anyChannel.Request(req); 

     // assume we're OK 
     if (!response.IsFault) 
     { 
      // get the body content of the reply 
      var content = response.GetReaderAtBodyContents(); 
      // convert to string 
      var xdoc = XDocument.Load(content.ReadSubtree()); 
      result = xdoc.ToString(); 
     } 
     else 
     { 
      //throw or handle 
      throw new Exception("panic"); 
     } 
    } 
    return result; 
} 
:あなたが越えてあなたの設定ファイル内の他の構成を必要としません

var result = CallService(
    @"<GetData xmlns=""http://tempuri.org/""><value>42</value></GetData>", 
    ConfigurationManager.AppSettings["serviceLink"], 
    ConfigurationManager.AppSettings["serviceSoapAction"]); 

// example without using appSettings 
var result2 = CallService(
    @"<GetValues xmlns=""http://tempuri.org/""></GetValues>", 
    "http://localhost:58642/service.svc", 
    "http://tempuri.org/IService/GetValues"); 

お知らせ:

<appSettings> 
    <add key="serviceLink" value="http://localhost:58642/service.svc"/> 
    <add key="serviceSoapAction" value="http://tempuri.org/IService/GetData"/> 
</appSettings> 

は、SOAPアクションを把握するために、サービスのWSDLを使用します。

<wsdl:binding name="BasicHttpBinding_IService" type="tns:IService"> 
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> 
    <wsdl:operation name="GetData"> 
     <soap:operation soapAction="http://tempuri.org/IService/GetData" style="document"/> 

とそのportTypeのとメッセージを通じてそのルートに従うことによって、あなたがタイプ見つける:あなたはGetDataのためのXMLペイロードの形状を構築することができ

<wsdl:types> 
    <xs:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/" xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
     <xs:import namespace="http://schemas.datacontract.org/2004/07/"/> 
     <xs:element name="GetData"> 
     <xs:complexType> 
      <xs:sequence> 
      <xs:element minOccurs="0" name="value" type="xs:int"/> 
      </xs:sequence> 
     </xs:complexType> 
     </xs:element> 

、そこからの:

<GetData xmlns="http://tempuri.org/"> 
    <value>42</value> 
</GetData> 
関連する問題