構成ファイルを使用しない WCF 構成
-
09-06-2019 - |
質問
構成ファイルを使用せずにプログラムで WCF サービスを公開する方法の良い例を知っている人はいますか?WCF ではサービス オブジェクト モデルがはるかに充実しているため、それが可能であることはわかっています。ただ、その方法の例を見たことがありません。逆に、設定ファイルなしでの消費もどのように行われるのか見てみたいと思います。
誰かが尋ねる前に、私には構成ファイルを使わずにこれを行うという非常に具体的なニーズがあります。通常はそのような行為はお勧めしませんが、前述したように、この場合は非常に特殊なニーズがあります。
解決
私が発見したように、構成ファイルなしで Web サービスを利用するのは非常に簡単です。バインディング オブジェクトとアドレス オブジェクトを作成し、それらをクライアント プロキシのコンストラクターまたは汎用の ChannelFactory インスタンスに渡すだけです。デフォルトの app.config を見て、使用する設定を確認し、プロキシをインスタンス化する静的ヘルパー メソッドをどこかに作成します。
internal static MyServiceSoapClient CreateWebServiceInstance() {
BasicHttpBinding binding = new BasicHttpBinding();
// I think most (or all) of these are defaults--I just copied them from app.config:
binding.SendTimeout = TimeSpan.FromMinutes( 1 );
binding.OpenTimeout = TimeSpan.FromMinutes( 1 );
binding.CloseTimeout = TimeSpan.FromMinutes( 1 );
binding.ReceiveTimeout = TimeSpan.FromMinutes( 10 );
binding.AllowCookies = false;
binding.BypassProxyOnLocal = false;
binding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
binding.MessageEncoding = WSMessageEncoding.Text;
binding.TextEncoding = System.Text.Encoding.UTF8;
binding.TransferMode = TransferMode.Buffered;
binding.UseDefaultWebProxy = true;
return new MyServiceSoapClient( binding, new EndpointAddress( "http://www.mysite.com/MyService.asmx" ) );
}
他のヒント
IIS ホスティングの web.config で System.ServiceModel セクションの使用を排除することに興味がある場合は、その方法の例をここに投稿しました (http://bejabbers2.blogspot.com/2010/02/wcf-zero-config-in-net-35-part-ii.html)。ServiceHost をカスタマイズしてメタデータと wshttpbinding エンドポイントの両方を作成する方法を示します。追加のコーディングを必要としない汎用的な方法でこれを実行します。.NET 4.0 にすぐにアップグレードしない人にとって、これは非常に便利です。
これは完全で動作するコードです。とても役立つと思います。検索しても完全なコードが見つからなかったので、完全で動作するコードを載せようとしました。幸運を。
public class ValidatorClass
{
WSHttpBinding BindingConfig;
EndpointIdentity DNSIdentity;
Uri URI;
ContractDescription ConfDescription;
public ValidatorClass()
{
// In constructor initializing configuration elements by code
BindingConfig = ValidatorClass.ConfigBinding();
DNSIdentity = ValidatorClass.ConfigEndPoint();
URI = ValidatorClass.ConfigURI();
ConfDescription = ValidatorClass.ConfigContractDescription();
}
public void MainOperation()
{
var Address = new EndpointAddress(URI, DNSIdentity);
var Client = new EvalServiceClient(BindingConfig, Address);
Client.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.PeerTrust;
Client.Endpoint.Contract = ConfDescription;
Client.ClientCredentials.UserName.UserName = "companyUserName";
Client.ClientCredentials.UserName.Password = "companyPassword";
Client.Open();
string CatchData = Client.CallServiceMethod();
Client.Close();
}
public static WSHttpBinding ConfigBinding()
{
// ----- Programmatic definition of the SomeService Binding -----
var wsHttpBinding = new WSHttpBinding();
wsHttpBinding.Name = "BindingName";
wsHttpBinding.CloseTimeout = TimeSpan.FromMinutes(1);
wsHttpBinding.OpenTimeout = TimeSpan.FromMinutes(1);
wsHttpBinding.ReceiveTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.SendTimeout = TimeSpan.FromMinutes(1);
wsHttpBinding.BypassProxyOnLocal = false;
wsHttpBinding.TransactionFlow = false;
wsHttpBinding.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard;
wsHttpBinding.MaxBufferPoolSize = 524288;
wsHttpBinding.MaxReceivedMessageSize = 65536;
wsHttpBinding.MessageEncoding = WSMessageEncoding.Text;
wsHttpBinding.TextEncoding = Encoding.UTF8;
wsHttpBinding.UseDefaultWebProxy = true;
wsHttpBinding.AllowCookies = false;
wsHttpBinding.ReaderQuotas.MaxDepth = 32;
wsHttpBinding.ReaderQuotas.MaxArrayLength = 16384;
wsHttpBinding.ReaderQuotas.MaxStringContentLength = 8192;
wsHttpBinding.ReaderQuotas.MaxBytesPerRead = 4096;
wsHttpBinding.ReaderQuotas.MaxNameTableCharCount = 16384;
wsHttpBinding.ReliableSession.Ordered = true;
wsHttpBinding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(10);
wsHttpBinding.ReliableSession.Enabled = false;
wsHttpBinding.Security.Mode = SecurityMode.Message;
wsHttpBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Certificate;
wsHttpBinding.Security.Transport.ProxyCredentialType = HttpProxyCredentialType.None;
wsHttpBinding.Security.Transport.Realm = "";
wsHttpBinding.Security.Message.NegotiateServiceCredential = true;
wsHttpBinding.Security.Message.ClientCredentialType = MessageCredentialType.UserName;
wsHttpBinding.Security.Message.AlgorithmSuite = System.ServiceModel.Security.SecurityAlgorithmSuite.Basic256;
// ----------- End Programmatic definition of the SomeServiceServiceBinding --------------
return wsHttpBinding;
}
public static Uri ConfigURI()
{
// ----- Programmatic definition of the Service URI configuration -----
Uri URI = new Uri("http://localhost:8732/Design_Time_Addresses/TestWcfServiceLibrary/EvalService/");
return URI;
}
public static EndpointIdentity ConfigEndPoint()
{
// ----- Programmatic definition of the Service EndPointIdentitiy configuration -----
EndpointIdentity DNSIdentity = EndpointIdentity.CreateDnsIdentity("tempCert");
return DNSIdentity;
}
public static ContractDescription ConfigContractDescription()
{
// ----- Programmatic definition of the Service ContractDescription Binding -----
ContractDescription Contract = ContractDescription.GetContract(typeof(IEvalService), typeof(EvalServiceClient));
return Contract;
}
}
サーバー上では簡単ではありません 側..
クライアント側では、次を使用できます チャンネルファクトリー
すべての WCF 構成はプログラムで実行できます。したがって、構成ファイルなしでサーバーとクライアントの両方を作成することができます。
Juval Lowy 著『Programming WCF Services』という書籍をお勧めします。この本には、プログラムによる構成の例が多数掲載されています。
クライアント側でもサーバー側でも非常に簡単に実行できます。Juval Lowy の本には優れた例が記載されています。
設定ファイルに関するあなたのコメントに関しては、コードで設定ファイルを実行するのに次ぐのは、設定ファイルのほうが下手だと言えます。構成ファイルは、サーバーに接続するすべてのクライアントを制御し、それらが確実に更新され、ユーザーがそれらを見つけて変更できないようにする場合に役立ちます。WCF 構成ファイル モデルは制限があり、設計がやや難しく、メンテナンスの悪夢であることがわかりました。全体として、構成ファイルをデフォルトの方法にするという MS の決定は非常に不適切だったと思います。
編集:構成ファイルで実行できないことの 1 つは、デフォルト以外のコンストラクターを使用してサービスを作成することです。これにより、WCF では静的/グローバル変数、シングルトン、その他の種類の無意味な変数が発生します。
このトピックに関する以下のリンクのブログ投稿が非常に興味深いと思いました。
私が気に入っているアイデアの 1 つは、構成から適切な WCF オブジェクトにバインディング、動作、またはアドレス XML セクションを渡して、それにプロパティの割り当てを処理させることができるというものですが、現在これはできません。
Web 上の他のユーザーと同様に、私も WCF 実装でホスティング アプリケーション (.NET 2.0 Windows サービス) とは異なる構成ファイルを使用する必要があるという点で問題を抱えています。
http://salvoz.com/blog/2007/12/09/programmatically-setting-wcf-configuration/