2009-04-28 11 views
7

Ho un'applicazione Web che utilizza un numero di servizi WCF. Dispongo la mia applicazione web in vari ambienti (dev, UAT, produzione, ecc.). L'URL di ciascun servizio WCF è diverso per ogni ambiente. Sto usando .NET 3.5 e basicHttpBinding sModifica dell'URL di riferimento del servizio WCF in base all'ambiente

L'applicazione Web utilizza un framework per supportare impostazioni specifiche della macchina nel mio file web.config. Quando un'istanza di un'istanza di un client servizio WCF che io chiamo una funzione che crea l'istanza del client WCF Service utilizzando l'overload costruttore che accetta gli argomenti:

System.ServiceModel.Channels.Binding binding, 
System.ServiceModel.EndpointAddress remoteAddress 

In sostanza la configurazione <system.serviceModel><bindings><basicHttpBinding><binding> nel web.config è stato replicato nel codice C#.

Questo approccio funziona bene.

Tuttavia, ora devo migliorare questo approccio per lavorare con un servizio WCF che utilizza un certificato X509. Questo significa che devo replicare le seguenti impostazioni aggiuntive nel web.config in codice C#:

<!-- inside the binding section --> 
<security mode="Message"> 
    <transport clientCredentialType="None" proxyCredentialType="None" realm="" /> 
    <message clientCredentialType="Certificate" algorithmSuite="Default" /> 
</security> 


<behaviors> 
    <endpointBehaviors> 
    <behavior name="MyServiceBehaviour"> 
     <clientCredentials> 
     <clientCertificate storeLocation="LocalMachine" storeName="My" 
      x509FindType="FindByThumbprint" findValue="1234abcd" /> 
     <serviceCertificate> 
      <defaultCertificate storeLocation="LocalMachine" storeName="My" 
      x509FindType="FindByThumbprint" findValue="5678efgh" /> 
      <authentication trustedStoreLocation="LocalMachine" 
      certificateValidationMode="None" /> 
     </serviceCertificate> 
     </clientCredentials> 
    </behavior> 
    </endpointBehaviors> 
</behaviors> 

Sto avendo qualche difficoltà a capire come codificare questa configurazione in C#.

Due domande

  • Qualcuno può raccomandare un approccio migliore per gestire gli URL di riferimento di servizio WCF in più ambienti?
  • In alternativa, qualche suggerimento su come replicare la sezione web.config sopra in C# saranno accolti
+1

Sono state aggiunte alcune considerazioni aggiuntive alla mia risposta: è possibile utilizzare i binding denominati ecc. In modo tale che sia possibile determinare il nome in base all'ambiente in uso e quindi caricare i valori appropriati dal file di configurazione. –

+0

La seguente domanda si riferisce a questo http://stackoverflow.com/questions/798684/programmatically-set-identity-on-wcf-endpointaddress –

+0

Mi rendo conto che lo stai facendo in codice piuttosto che nei file di configurazione, ma perché non usare config le trasformazioni e inserire le impostazioni specifiche dell'ambiente nel file di configurazione appropriato (Web.config.dev, Web.config.Test, Web.config.Release, ecc.)? – camainc

risposta

1

Il codice seguente replica la configurazione nella mia domanda iniziale:

myClient.ClientCredentials.ClientCertificate.SetCertificate(
    StoreLocation.LocalMachine, 
    StoreName.My, 
    X509FindType.FindByThumbprint, 
    "1234abcd"); 

myClient.ClientCredentials.ServiceCertificate.SetDefaultCertificate(
    StoreLocation.LocalMachine, 
    StoreName.My, 
    X509FindType.FindByThumbprint, 
    "5678efgh"); 

myClient.ClientCredentials.ServiceCertificate.Authentication.TrustedStoreLocation = StoreLocation.LocalMachine; 
myClient.ClientCredentials.ServiceCertificate.Authentication.CertificateValidationMode = X509CertificateValidationMode.None; 

Nel codice di produzione i due valori thumbprint sono memorizzati nella appSettings nel file web.config.

4

Un possibile approccio potrebbe essere quello di "esternare" alcune parti della configurazione <system.serviceModel> in file esterni , uno per ambiente.

E.g. abbiamo "bindings.dev.config" e "bindings.test.config", che abbiamo quindi fare riferimento nel nostro web.config principale in questo modo:

<system.serviceModel> 
    <bindings configSource="bindings.dev.config" /> 
</system.serviceModel> 

In questo modo, tutto ciò che serve per passare da DEV a PROD è questa una riga di XML di configurazione.

Fondamentalmente, in .NET 2.0 config, qualsiasi elemento di configurazione può essere "esternalizzato". Tuttavia, non è possibile esternare direttamente i configGroups (come "system.serviceModel") - è necessario essere sul livello "configuration element".

Marc

EDIT: Ok, così NO config modificare modifiche per passare da ambienti ..... In questo caso, probabilmente dovete sognare uno schema di denominazione, per esempio nominare i collegamenti, i comportamenti e gli endpoint in modo tale da poterli distinguere in fase di runtime.

Qualcosa di simile:

<bindings> 
    <binding name="Default_DEV"> 
    ..... 
    </binding> 
    <binding name="Default_PROD"> 
    ..... 
    </binding> 
</bindings> 

in questo modo, si potrebbe costruire il nome dell'elemento che si desidera (ad esempio vincolante "Default_PROD") dal codice e l'ambiente si sta eseguendo in, e poi prendete la config corrispondente dal file di configurazione che contiene tutte le impostazioni di configurazione per tutti gli ambienti.

+0

Ho davvero bisogno di un'opzione che richiede zero modifiche al file di configurazione tra gli ambienti ... –

1

Non utilizziamo affatto i file web.config, specifichiamo tutto a livello di codice e cariciamo tutta la configurazione da un database centralizzato.

+0

Usi servizi WCF che richiedono certificati X509? –

+1

Spiacente, ma abbiamo diverse opzioni e tipi di binding supportiamo net.tcp, basicHttp, WS *). A seconda dell'URL, cerchiamo diverse configurazioni nel database e configuriamo dinamicamente come appropriato. È relativamente semplice e non richiede molta configurazione. Possiamo anche distribuire in un ambiente Web-farm e consentirne la configurazione centralizzata. – Bigtoe

+0

Nessun problema: sembra un buon approccio –

Problemi correlati