2009-06-08 130 views
49

我想以編程方式修改我的app.config文件來設置其服務端點文件應使用。在運行時執行此操作的最佳方式是什麼?作爲參考:如何以編程方式修改WCF 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> 
+18

鍊金,你可能想,如果你發現自己需要在運行時修改一個app.config重新評估你的答案接受 – 2012-02-23 19:54:40

+0

的選擇,根據我的經驗,這可能意味着你缺少一個.NET提供的手段完成你正在嘗試做的事情。亞歷克斯諾特的答案在這種情況下指出它,如果你真的想要做的是擊中一個不同的地址,在同一個確切的服務託管。 – 2014-04-09 17:18:52

回答

2

我想你想要的是在運行時換出一個版本的配置文件,如果使創建配置文件的副本(也給它的相關擴展喜歡的.debug或.Release)它具有正確的地址(它提供了一個調試版本和一個運行時版本),並根據構建類型創建一個複製正確文件的構建步驟。

下面是我在它覆蓋用正確版本的輸出文件(調試/運行)

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

在過去使用的postbuild事件的例子: $(PROJECTDIR)是項目所在的目錄配置文件位於 $(ConfigurationName)是有效配置生成類型

編輯: 請參閱馬克的回答關於如何做到這一點編程的詳細說明。

+0

我以編程方式結束了這個工作,謝謝。 – alchemical 2009-06-09 17:46:43

+0

您不能使用不在.config中的綁定名稱。 「測試」將返回一個錯誤。這是一個問題,因爲通道工廠緩存只有在指定綁定配置名稱時纔會發生,而不是綁定對象=( – Sprague 2010-08-26 19:51:52

94

這是在客戶端的東西??

如果是這樣,你需要創建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()方法來打開服務主機。

如果您希望能夠在運行時動態選擇要使用的配置,可以定義多個配置,每個配置都有唯一的名稱,然後調用相應的構造函數(用於服務主機或代理客戶機)以及您希望使用的配置名稱。

E.g.你可以輕鬆擁有:

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

(三個不同的名字,不同的參數,通過指定不同的bindingConfigurations),然後只選擇一個正確的實例化你的服務器(或客戶代理)。

但在這兩種情況下 - 服務器和客戶端 - 你實際上是創建服務主機或代理客戶端之前來接。 一旦創建,這些都是不可改變 - 你不能調整它們一旦他們啓動和運行。

馬克

+0

如何以編程方式將綁定配置和合同添加到端點? – 2010-04-22 23:58:46

+0

查看我的答案的頂部 - 您需要創建一個綁定和一個端點地址,然後根據這兩個項目創建服務端點(在服務器端)或您的客戶端代理。你不能「添加」一個綁定到一個端點 - 一個端點包含三個地址(URI),綁定和合約 – 2010-04-23 05:02:28

+11

這應該是正確的答案,它更加詳細和有用。 – 2010-10-06 15:40:22

26

我用下面的代碼在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"; 
     } 
    } 
} 
11
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

2

我已經修改和擴展馬爾科姆史文的代碼通過它的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"; 
    } 
} 

}

2

這是你可以用它來更新應用程序配置文件,即使沒有定義的配置節最短代碼:

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

這是非常輕鬆修改config中的uri或config中的綁定信息。 這是你想要的嗎?

4

這個短代碼爲我工作:

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.ConfigurationSystem.ServiceModel組件來完成這項工作。

乾杯

1

你可以這樣說:

  • 保持你的設置,在一個單獨的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(); 
    
1

對於它的價值,我需要ŧ O更新爲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(); 
相關問題