2008-09-17 12 views
14

私は、デスクトップアプリケーションによって動的に接続されたWCF Webサービスを用意しています。WCFを簡単に設定する

私の問題は、WCFが動作するために必要な、本当に詳細な設定です。 SSLを動作させるにはカスタム設定が必要です。 MTOMや何か他のものを動かすことはもっと必要です。あなたは圧縮したいですか?ここでもう一度やります...

WCFは本当に強力です。あなたはさまざまな方法で接続することができますが、詳細な設定がたくさんあるようです。ホストとクライアントが完全に一致しない場合は、エラーの解読が難しくなります。

私はデスクトップアプリケーションを構成するのがはるかに簡単で、理想的には何らかの自動検出を実現したいと考えています。デスクトップアプリのユーザーは、URLを入力できるだけで、残りの部分は処理する必要があります。

これを行うには良い方法がありますか?

私はVisual Studioがあなたのために設定をすることができますが、私はデスクトップアプリケーションがさまざまな異なるサーバー設定に基づいてそれを行うことができるようにしたいと思います。

私は、VSのツールを外部で使うことができると知っていますが、WCFの専門家でなくてもデスクトップアプリケーションのユーザーを探しています。私はMSがこれを意図的に複雑にしたことを知っています。

WCF設定の自動検出を可能にする方法、メカニズム、サードパーティ製のライブラリなどはありますか?

+0

"私はMSがこれを意図的に複雑にしたのは知っている" –

+0

多分それは不公平だ。 MSは意図的に変更することができるすべての設定を可能にしましたが、基本設定にはWCFの本とプログラミングの経験が必要です。 – Keith

答えて

9

エンドポイントに関するすべての情報は、サービスのメタデータで利用できます。クライアントの記述によって、サービスのメタデータを調査し、クライアントを構成できます。コード例については、Juval Lowyの優れたMex Explorerを調べることができます。

1

ありがとう、それは便利なコード(+1)でした。

これはちょっと面倒ですが、いくつかのバグ(大文字と小文字を区別する必要のないチェックなど)があり、必要のないUI機能があり、たくさんのコードを繰り返します。

私はそれから実際の発見メカニズムを取り、それを書き直して、ほとんどそれを働かせました(接続していますが、いくつかのフィッシングが必要です)。 mainメソッドが使用する

まず、いくつかのutil機能:

/// <summary>If the url doesn't end with a WSDL query string append it</summary> 
static string AddWsdlQueryStringIfMissing(string input) 
{ 
    return input.EndsWith("?wsdl", StringComparison.OrdinalIgnoreCase) ? 
     input : input + "?wsdl"; 
} 

/// <summary>Imports the meta data from the specified location</summary> 
static ServiceEndpointCollection GetEndpoints(BindingElement bindingElement, Uri address, MetadataExchangeClientMode mode) 
{ 
    CustomBinding binding = new CustomBinding(bindingElement); 
    MetadataSet metadata = new MetadataExchangeClient(binding).GetMetadata(address, mode); 
    return new WsdlImporter(metadata).ImportAllEndpoints(); 
} 

次に接続する別の方法を試行し、エンドポイントを返すメソッド:

public static ServiceEndpointCollection Discover(string url) 
{ 
    Uri address = new Uri(url); 
    ServiceEndpointCollection endpoints = null; 

    if (string.Equals(address.Scheme, "http", StringComparison.OrdinalIgnoreCase)) 
    { 
     var httpBindingElement = new HttpTransportBindingElement(); 

     //Try the HTTP MEX Endpoint 
     try { endpoints = GetEndpoints(httpBindingElement, address, MetadataExchangeClientMode.MetadataExchange); } 
     catch { } 

     //Try over HTTP-GET 
     if (endpoints == null) 
      endpoints = GetEndpoints(httpBindingElement, 
       new Uri(AddWsdlQueryStringIfMissing(url)), MetadataExchangeClientMode.HttpGet); 
    } 
    else if (string.Equals(address.Scheme, "https", StringComparison.OrdinalIgnoreCase)) 
    { 
     var httpsBindingElement = new HttpsTransportBindingElement(); 

     //Try the HTTPS MEX Endpoint 
     try { endpoints = GetEndpoints(httpsBindingElement, address, MetadataExchangeClientMode.MetadataExchange); } 
     catch { } 

     //Try over HTTP-GET 
     if (endpoints == null) 
      endpoints = GetEndpoints(httpsBindingElement, 
       new Uri(AddWsdlQueryStringIfMissing(url)), MetadataExchangeClientMode.HttpGet); 
    } 
    else if (string.Equals(address.Scheme, "net.tcp", StringComparison.OrdinalIgnoreCase)) 
     endpoints = GetEndpoints(new TcpTransportBindingElement(), 
      address, MetadataExchangeClientMode.MetadataExchange); 

    else if (string.Equals(address.Scheme, "net.pipe", StringComparison.OrdinalIgnoreCase)) 
     endpoints = GetEndpoints(new NamedPipeTransportBindingElement(), 
      address, MetadataExchangeClientMode.MetadataExchange); 

    return endpoints; 
} 
1

これを行うための別の方法が用意されました私は元の質問をしたときに利用できませんでした。 MicrosoftはWCFサービス用のRESTをサポートしています。

  • RESTを使用することの欠点は、WSDLを失うことです。
  • アップサイドは最小限の設定で、WCF契約インタフェースは引き続き機能します!

あなたはサイトにこれらの追加WebInvokeまたはWebGet

//get a user - note that this can be cached by IIS and proxies 
[WebGet] 
User GetUser(string id) 

//post changes to a user 
[WebInvoke] 
void SaveUser(string id, User changes) 

のいずれかを使用して操作System.ServiceModel.Web

マークへの新しい参照をする必要があります簡単です - .svcファイルを追加:

<%@ServiceHost 
    Service="MyNamespace.MyServiceImplementationClass" 
    Factory="System.ServiceModel.Activation.WebServiceHostFactory" %> 

工場出荷時は、ASP.netにエンドポイントのアクティブ化方法を指示します - サーバー側の設定は一切必要ありません!

あなたが任意のより多くの(私は他の回答で持っているとして、または1つを自動検出)エンドポイントを指定する必要はありませんことを除き、その後、あなたのChannelFactoryを構築することは、ほとんど変化していない

var cf = new WebChannelFactory<IMyContractInterface>(); 
var binding = new WebHttpBinding(); 

cf.Endpoint.Binding = binding; 
cf.Endpoint.Address = new EndpointAddress(new Uri("mywebsite.com/myservice.svc")); 
cf.Endpoint.Behaviors.Add(new WebHttpBehavior()); 

IMyContractInterface wcfClient = cf.CreateChannel(); 

var usr = wcfClient.GetUser("demouser"); 
// and so on... 

なお、私は指定されていないか、クライアントの設定を発見しました - 必要なローカル設定はありません!

もう1つの大きな利点は、JSONとRESTを簡単に処理できるJava、ActionScript、Javascript、Silverlightなどで同じWCFサービスを使用できるJSONシリアライズに簡単に切り替えることができることです。

+0

これが変更された理由について私はまたブログしました:http://bizvprog.blogspot.com/2009/11/giving-up-on-soap-for-good.html – Keith

関連する問題