Configurazione WCF senza un file di configurazione

Qualcuno sa di un buon esempio di come esporre un servizio WCF in modo programmatico senza l’uso di un file di configurazione? So che il modello degli oggetti di servizio è molto più ricco ora con WCF, quindi so che è ansible. Non ho appena visto un esempio su come farlo. Al contrario, mi piacerebbe vedere come si consumano anche senza un file di configurazione.

Prima che qualcuno chieda, ho una necessità molto specifica di farlo senza file di configurazione. Normalmente non consiglierei una pratica del genere, ma come ho detto, c’è un bisogno molto specifico in questo caso.

Consumare un servizio web senza un file di configurazione è molto semplice, come ho scoperto. È sufficiente creare un object di binding e un object di indirizzo e passarli al costruttore del proxy client oa un’istanza generica di ChannelFactory. Puoi guardare l’app.config predefinita per vedere quali impostazioni utilizzare, quindi creare un metodo di supporto statico da qualche parte che istanzia il tuo proxy:

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" ) ); } 

Se sei interessato ad eliminare l’uso della sezione System.ServiceModel nel web.config per l’hosting IIS, ho pubblicato un esempio di come farlo qui ( http://bejabbers2.blogspot.com/2010/02/wcf -zero-config-in-net-35-part-ii.html ). Vi mostrerò come personalizzare un ServiceHost per creare sia endpoint di metadati che wshttpbinding. Lo faccio in un modo generico che non richiede una codifica aggiuntiva. Per coloro che non stanno effettuando l’aggiornamento a .NET 4.0, questo può essere piuttosto conveniente.

Qui, questo è completo e funzionante. Penso che ti aiuterà molto. Stavo cercando e non ho mai trovato un codice completo, ecco perché ho provato a inserire codice completo e funzionante. In bocca al lupo.

 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; } } 

Non è facile dal lato server ..

Per il lato client, è ansible utilizzare ChannelFactory

Tutta la configurazione di WCF può essere eseguita in modo programmatico. Quindi è ansible creare sia server che client senza un file di configurazione.

Raccomando il libro “Programmazione servizi WCF” di Juval Lowy, che contiene molti esempi di configurazione programmatica.

È molto facile da eseguire sia dal lato client che lato server. Il libro di Juval Lowy ha esempi eccellenti.

Per quanto riguarda il tuo commento sui file di configurazione, direi che i file di configurazione sono i secondi di un uomo povero per farlo in codice. I file di configurazione sono ottimi quando controlli ogni client che si connetterà al tuo server e si assicurerà che siano aggiornati, e che gli utenti non possano trovarli e cambiare nulla. Trovo che il modello di file di configurazione di WCF sia limitante, leggermente difficile da progettare e un incubo di manutenzione. Tutto sumto, penso che sia stata una decisione molto scortese da parte di MS rendere i file di configurazione il modo predefinito di fare le cose.

EDIT: una delle cose che non puoi fare con il file di configurazione è creare servizi con costruttori non predefiniti. Ciò porta a variabili statiche / globali e singleton e altri tipi di non sense in WCF.

Ho trovato il post del blog al link sottostante su questo argomento molto interessante.

Un’idea che mi piace è quella di essere in grado di passare semplicemente un binding o un comportamento o di indirizzare la sezione XML dalla configurazione all’object WCF appropriato e lasciare che gestisca l’assegnazione delle proprietà – al momento non è ansible farlo.

Come gli altri sul Web, sto riscontrando problemi relativi alla necessità che l’implementazione della WCF utilizzi un file di configurazione diverso da quello della mia applicazione di hosting (che è un servizio Windows 2.0 di Windows).

http://salvoz.com/blog/2007/12/09/programmatically-setting-wcf-configuration/