49 votes

Comment modifier par programmation le paramètre d'adresse de point final WCF app.config?

J'aimerais modifier par programme mon fichier app.config pour définir le point de terminaison du fichier de service à utiliser. Quelle est la meilleure façon de faire cela au moment de l'exécution? Pour référence:

 <endpoint address="http://mydomain/MyService.svc"
    binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IASRService"
    contract="ASRService.IASRService" name="WSHttpBinding_IASRService">
    <identity>
        <dns value="localhost" />
    </identity>
</endpoint>
 

95voto

marc_s Points 321990

Est-ce du côté client de choses??

Si oui, vous devez créer une instance de WsHttpBinding, et un EndpointAddress, puis de transmettre ces deux pour le client du proxy constructeur qui prend ces deux paramètres.

// using System.ServiceModel;
WSHttpBinding binding = new WSHttpBinding();
EndpointAddress endpoint = new EndpointAddress(new Uri("http://localhost:9000/MyService"));

MyServiceClient client = new MyServiceClient(binding, endpoint);

Si c'est sur le serveur côté des choses, vous aurez besoin de programmation pour créer votre propre instance de ServiceHost, et ajouter les points de terminaison du service.

ServiceHost svcHost = new ServiceHost(typeof(MyService), null);

svcHost.AddServiceEndpoint(typeof(IMyService), 
                           new WSHttpBinding(), 
                           "http://localhost:9000/MyService");

Bien sûr, vous pouvez avoir plusieurs de ces points de terminaison de service ajoutés à votre hôte de service. Une fois que vous avez terminé, vous devez ouvrir l'hôte de service en appelant le .La méthode Open ().

Si vous voulez être en mesure de dynamiquement lors de l'exécution - choisir la configuration à utiliser, vous pouvez définir plusieurs configurations, chacune avec un nom unique, et ensuite appeler le constructeur approprié (pour votre service d'accueil, ou votre client de proxy) avec le nom de la configuration que vous souhaitez utiliser.

E. g. vous auriez pu facilement:

<endpoint address="http://mydomain/MyService.svc"
        binding="wsHttpBinding" bindingConfiguration="WSHttpBinding_IASRService"
        contract="ASRService.IASRService" 
        name="WSHttpBinding_IASRService">
        <identity>
            <dns value="localhost" />
        </identity>
</endpoint>

<endpoint address="https://mydomain/MyService2.svc"
        binding="wsHttpBinding" bindingConfiguration="SecureHttpBinding_IASRService"
        contract="ASRService.IASRService" 
        name="SecureWSHttpBinding_IASRService">
        <identity>
            <dns value="localhost" />
        </identity>
</endpoint>

<endpoint address="net.tcp://mydomain/MyService3.svc"
        binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IASRService"
        contract="ASRService.IASRService" 
        name="NetTcpBinding_IASRService">
        <identity>
            <dns value="localhost" />
        </identity>
</endpoint>

(trois noms différents, différents paramètres en spécifiant différents bindingConfigurations) et ensuite il suffit de choisir le bon pour instancier votre serveur (ou proxy client).

Mais dans les deux cas - server - client et que vous avez à choisir avant la création du service de l'hôte ou le client du proxy. Une fois créées, elles sont immuables - vous ne pouvez pas régler une fois qu'ils sont en place et en cours d'exécution.

Marc

26voto

Malcolm Swaine Points 231

J'utilise le code suivant pour modifier l'adresse du noeud final dans le fichier App.Config. Vous souhaiterez peut-être modifier ou supprimer l'espace de noms avant son utilisation.

 using System;
using System.Xml;
using System.Configuration;
using System.Reflection;
//...

namespace Glenlough.Generations.SupervisorII
{
    public class ConfigSettings
    {

        private static string NodePath = "//system.serviceModel//client//endpoint";
        private ConfigSettings() { }

        public static string GetEndpointAddress()
        {
            return ConfigSettings.loadConfigDocument().SelectSingleNode(NodePath).Attributes["address"].Value;
        }

        public static void SaveEndpointAddress(string endpointAddress)
        {
            // load config document for current assembly
            XmlDocument doc = loadConfigDocument();

            // retrieve appSettings node
            XmlNode node = doc.SelectSingleNode(NodePath);

            if (node == null)
                throw new InvalidOperationException("Error. Could not find endpoint node in config file.");

            try
            {
                // select the 'add' element that contains the key
                //XmlElement elem = (XmlElement)node.SelectSingleNode(string.Format("//add[@key='{0}']", key));
                node.Attributes["address"].Value = endpointAddress;

                doc.Save(getConfigFilePath());
            }
            catch( Exception e )
            {
                throw e;
            }
        }

        public static XmlDocument loadConfigDocument()
        {
            XmlDocument doc = null;
            try
            {
                doc = new XmlDocument();
                doc.Load(getConfigFilePath());
                return doc;
            }
            catch (System.IO.FileNotFoundException e)
            {
                throw new Exception("No configuration file found.", e);
            }
        }

        private static string getConfigFilePath()
        {
            return Assembly.GetExecutingAssembly().Location + ".config";
        }
    }
}
 

11voto

Alex Knott Points 81
 SomeServiceClient client = new SomeServiceClient();

var endpointAddress = client.Endpoint.Address; //gets the default endpoint address

EndpointAddressBuilder newEndpointAddress = new EndpointAddressBuilder(endpointAddress);
                newEndpointAddress.Uri = new Uri("net.tcp://serverName:8000/SomeServiceName/");
                client = new SomeServiceClient("EndpointConfigurationName", newEndpointAddress.ToEndpointAddress());
 

Je l'ai fait comme ça. La bonne chose est qu'il récupère toujours le reste de vos paramètres de liaison de point final à partir de la configuration et remplace simplement l'URI .

5voto

realbizkit Points 16

ce code court a fonctionné pour moi:

 Configuration wConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
ServiceModelSectionGroup wServiceSection = ServiceModelSectionGroup.GetSectionGroup(wConfig);

ClientSection wClientSection = wServiceSection.Client;
wClientSection.Endpoints[0].Address = <your address>;
wConfig.Save();
 

Bien sûr, vous devez créer le proxy ServiceClient APRÈS que la configuration ait changé. Vous devez également référencer les assemblys System.Configuration et System.ServiceModel pour que cela fonctionne.

À votre santé

1voto

almog.ori Points 5145

Je pense que ce que vous voulez est de permuter à l'exécution d'une version de votre fichier de configuration, si donc créer une copie de votre fichier de configuration (aussi lui donner l'extension concernée comme .Debug ou .De presse), qui a les bonnes adresses (ce qui vous donne une version de débogage et une version d'exécution ) et de créer un postbuild étape qui copie le bon fichier en fonction du type de build.

Voici un exemple d'un postbuild événement que j'ai utilisé dans le passé qui remplace le fichier de sortie avec la version correcte (debug/runtime)

copy "$(ProjectDir)ServiceReferences.ClientConfig.$(ConfigurationName)" "$(ProjectDir)ServiceReferences.ClientConfig" /Y

où : $(ProjectDir) est le projet le répertoire où les fichiers de configuration sont situés $(ConfigurationName) est la configuration active type de build

EDIT: Veuillez voir la réponse de Marc, pour une explication détaillée sur la façon de le faire par programmation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X