Подтвердить что ты не робот

Как программно изменить настройку адреса конечной точки WCF app.config?

Я хотел бы программно изменить файл app.config, чтобы указать, какая конечная точка файла сервиса должна использоваться. Каков наилучший способ сделать это во время выполнения? Для справки:

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

Ответ 1

Я думаю, что вы хотите поменять время исполнения версии вашего файла конфигурации, если это так, создайте копию вашего файла конфигурации (также укажите ему соответствующее расширение, например .Debug или .Release), в котором указаны правильные адреса ( который дает вам отладочную версию и версию исполнения) и создайте шаг postbuild, который копирует правильный файл в зависимости от типа сборки.

Вот пример события postbuild, которое я использовал в прошлом, которое переопределяет выходной файл с правильной версией (debug/runtime)

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

где: $ (ProjectDir) - это каталог проекта, в котором расположены файлы конфигурации $ (ConfigurationName) - это тип конфигурации активной конфигурации

EDIT: См. Ответ Marc для подробного объяснения того, как это сделать программно.

Ответ 2

Это на стороне клиента?

Если это так, вам нужно создать экземпляр WsHttpBinding и EndpointAddress, а затем передать эти два в клиентский конструктор прокси, который берет эти два в качестве параметров.

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

MyServiceClient client = new MyServiceClient(binding, endpoint);

Если это на стороне сервера, вам необходимо программно создать свой собственный экземпляр ServiceHost и добавить к нему соответствующие конечные точки службы.

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

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

Конечно, вы можете иметь несколько конечных точек обслуживания, добавленных на ваш хост-службы. Как только вы закончите, вам нужно открыть хост службы, вызвав метод .Open().

Если вы хотите иметь возможность динамически - во время выполнения - выберите, какую конфигурацию использовать, вы можете определить несколько конфигураций, каждый с уникальным именем, а затем вызвать соответствующий конструктор (для вашего хоста службы или вашего прокси-клиента) с именем конфигурации, которое вы хотите использовать.

например. вы можете легко:

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

(три разных имени, разные параметры, указав различные привязкиConfigurations), а затем просто выберите правильный, чтобы создать экземпляр вашего сервера (или клиентского прокси).

Но в обоих случаях - сервер и клиент - вы должны выбрать до фактического создания хоста службы или прокси-клиента. После создания они являются неизменяемыми - вы не можете их подстроить после их запуска.

Марк

Ответ 3

Я использую следующий код для изменения адреса конечной точки в файле App.Config. Вы можете захотеть изменить или удалить пространство имен перед использованием.

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

Ответ 4

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());

Я сделал это так. Хорошо, что он все еще берет остальные настройки привязки конечной точки из конфигурации и просто заменяет URI.

Ответ 5

этот короткий код работал у меня:

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

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

Конечно, вам нужно создать прокси-сервер ServiceClient ПОСЛЕ изменения конфигурации. Вам также необходимо обратиться к сборкам System.Configuration и System.ServiceModel, чтобы сделать эту работу.

Приветствия

Ответ 6

Я изменил и расширил код Malcolm Swaine, чтобы изменить конкретный node его атрибут name, а также изменить внешний файл конфигурации. Надеюсь, что это поможет.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Reflection;

namespace LobbyGuard.UI.Registration
{
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
        XmlNodeList nodes = doc.SelectNodes(NodePath);

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

            //If this isnt the node I want to change, look at the next one
            //Change this string to the name attribute of the node you want to change
            if (node.Attributes["name"].Value != "DataLocal_Endpoint1")
            {
                continue;
            }

            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());

                break;
            }
            catch (Exception e)
            {
                throw e;
            }
        }
    }

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

        // retrieve appSettings node
        XmlNodeList nodes = doc.SelectNodes(NodePath);

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

            //If this isnt the node I want to change, look at the next one
            if (node.Attributes["name"].Value != endpointName)
            {
                continue;
            }

            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(ConfigPath);

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

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

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

}

Ответ 7

Это самый короткий код, который вы можете использовать для обновления файла конфигурации приложения, даже если у него нет определенного раздела конфигурации:

void UpdateAppConfig(string param)
{
   var doc = new XmlDocument();
   doc.Load("YourExeName.exe.config");
   XmlNodeList endpoints = doc.GetElementsByTagName("endpoint");
   foreach (XmlNode item in endpoints)
   {
       var adressAttribute = item.Attributes["address"];
       if (!ReferenceEquals(null, adressAttribute))
       {
           adressAttribute.Value = string.Format("http://mydomain/{0}", param);
       }
   }
   doc.Save("YourExeName.exe.config");
}

Ответ 8

MyServiceClient client = new MyServiceClient(binding, endpoint);
client.Endpoint.Address = new EndpointAddress("net.tcp://localhost/webSrvHost/service.svc");
client.Endpoint.Binding = new NetTcpBinding()
            {
                Name = "yourTcpBindConfig",
                ReaderQuotas = XmlDictionaryReaderQuotas.Max,
                ListenBacklog = 40 }

Очень легко изменить uri в конфигурации или информации привязки в config. Это то, что вы хотите?

Ответ 9

Вы можете сделать это следующим образом:

  • Сохраняйте свои настройки в отдельном XML файле и просматривайте его при создании прокси-сервера для вашей службы.

Например, я хочу изменить адрес конечной точки службы во время выполнения, поэтому у меня есть следующий файл ServiceEndpoint.xml.

     <?xml version="1.0" encoding="utf-8" ?>
     <Services>
        <Service name="FileTransferService">
           <Endpoints>
              <Endpoint name="ep1" address="http://localhost:8080/FileTransferService.svc" />
           </Endpoints>
        </Service>
     </Services>
  • Для чтения вашего xml:

     var doc = new XmlDocument();
     doc.Load(FileTransferConstants.Constants.SERVICE_ENDPOINTS_XMLPATH);
     XmlNodeList endPoints = doc.SelectNodes("/Services/Service/Endpoints");  
     foreach (XmlNode endPoint in endPoints)
     {
        foreach (XmlNode child in endPoint)
        {
            if (child.Attributes["name"].Value.Equals("ep1"))
            {
                var adressAttribute = child.Attributes["address"];
                if (!ReferenceEquals(null, adressAttribute))
                {
                    address = adressAttribute.Value;
                }
           }
       }
    }  
    
  • Затем получите файл web.config вашего клиента во время выполнения и назначьте адрес конечной точки службы следующим образом:

        Configuration wConfig = ConfigurationManager.OpenMappedExeConfiguration(new ExeConfigurationFileMap { ExeConfigFilename = @"C:\FileTransferWebsite\web.config" }, ConfigurationUserLevel.None);
        ServiceModelSectionGroup wServiceSection = ServiceModelSectionGroup.GetSectionGroup(wConfig);
    
        ClientSection wClientSection = wServiceSection.Client;
        wClientSection.Endpoints[0].Address = new Uri(address);
        wConfig.Save();
    

Ответ 10

Для чего мне стоит обновить порт и схему SSL для моей службы RESTFul. Это то, что я сделал. Извиняется, что это немного больше, чем оригинальный вопрос, но, надеюсь, полезный для кого-то.

// Don't forget to add references to System.ServiceModel and System.ServiceModel.Web

using System.ServiceModel;
using System.ServiceModel.Configuration;

var port = 1234;
var isSsl = true;
var scheme = isSsl ? "https" : "http";

var currAssembly = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
Configuration config = ConfigurationManager.OpenExeConfiguration(currAssembly);

ServiceModelSectionGroup serviceModel = ServiceModelSectionGroup.GetSectionGroup(config);

// Get the first endpoint in services.  This is my RESTful service.
var endp = serviceModel.Services.Services[0].Endpoints[0];

// Assign new values for endpoint
UriBuilder b = new UriBuilder(endp.Address);
b.Port = port;
b.Scheme = scheme;
endp.Address = b.Uri;

// Adjust design time baseaddress endpoint
var baseAddress = serviceModel.Services.Services[0].Host.BaseAddresses[0].BaseAddress;
b = new UriBuilder(baseAddress);
b.Port = port;
b.Scheme = scheme;
serviceModel.Services.Services[0].Host.BaseAddresses[0].BaseAddress = b.Uri.ToString();

// Setup the Transport security
BindingsSection bindings = serviceModel.Bindings;
WebHttpBindingCollectionElement x =(WebHttpBindingCollectionElement)bindings["webHttpBinding"];
WebHttpBindingElement y = (WebHttpBindingElement)x.ConfiguredBindings[0];
var e = y.Security;

e.Mode = isSsl ? WebHttpSecurityMode.Transport : WebHttpSecurityMode.None;
e.Transport.ClientCredentialType = HttpClientCredentialType.None;

// Save changes
config.Save();

Ответ 11

посмотрите, размещаете ли вы клиентский раздел в правильном файле web.config. SharePoint имеет от 6 до 7 файлов конфигурации. http://msdn.microsoft.com/en-us/library/office/ms460914(v=office.14).aspx (http://msdn.microsoft.com/en-us/library/office/ms460914%28v=office.14%29.aspx)

Поместите это, вы можете просто попробовать

ServiceClient client = new ServiceClient("ServiceSOAP");