Loading System.ServiceModel Konfigurationsabschnitt mit ConfigurationManager


55

Mit C# .NET 3.5 und WCF versuche ich, einige der WCF-Konfiguration in einer Client-Anwendung (der Name des Servers, mit dem der Client eine Verbindung herstellt) zu schreiben.

Der offensichtliche Weg ist, ConfigurationManager zu verwenden, um den Konfigurationsabschnitt zu laden und die Daten zu schreiben, die ich benötige.

var serviceModelSection = ConfigurationManager.GetSection("system.serviceModel"); 

Wird immer Null angezeigt.

var serviceModelSection = ConfigurationManager.GetSection("appSettings"); 

Funktioniert perfekt.

Der Konfigurationsabschnitt ist in App.config vorhanden, aber aus bestimmten Gründen verweigert ConfigurationManager das Laden des Abschnitts system.ServiceModel.

Ich möchte manuell vermeiden, die xxx.exe.config-Datei laden und XPath verwenden, aber wenn ich darauf zurückgreifen muss, werde ich. Es scheint nur ein bisschen wie ein Hack.

Irgendwelche Vorschläge?

45

Das <system.serviceModel> Element ist für einen Konfigurationsabschnitt Gruppe, kein Abschnitt. Sie müssen System.ServiceModel.Configuration.ServiceModelSectionGroup.GetSectionGroup() verwenden, um die gesamte Gruppe zu erhalten.


55

http://mostlytech.blogspot.com/2007/11/programmatically-enumerate-wcf.html

// Automagically find all client endpoints defined in app.config 
ClientSection clientSection = 
    ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection; 

ChannelEndpointElementCollection endpointCollection = 
    clientSection.ElementInformation.Properties[string.Empty].Value as  ChannelEndpointElementCollection; 
List<string> endpointNames = new List<string>(); 
foreach (ChannelEndpointElement endpointElement in endpointCollection) 
{ 
    endpointNames.Add(endpointElement.Name); 
} 
// use endpointNames somehow ... 

scheint gut zu funktionieren.

+1

die verwirrende Linie für endpointCollection = clientSection.ElementInformation.Properties [string.Empty] .Wert als ChannelEndpointElementCollection; sollte vereinfacht werden zu clientSection.Endpoints; 23 okt. 132013-10-23 01:56:19


14

Dies ist, was ich suchte, dank @marxidad für den Zeiger.

public static string GetServerName() 
    { 
     string serverName = "Unknown"; 

     Configuration appConfig = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
     ServiceModelSectionGroup serviceModel = ServiceModelSectionGroup.GetSectionGroup(appConfig); 
     BindingsSection bindings = serviceModel.Bindings; 

     ChannelEndpointElementCollection endpoints = serviceModel.Client.Endpoints; 

     for(int i=0; i<endpoints.Count; i++) 
     { 
      ChannelEndpointElement endpointElement = endpoints[i]; 
      if (endpointElement.Contract == "MyContractName") 
      { 
       serverName = endpointElement.Address.Host; 
      } 
     } 

     return serverName; 
    } 

8

GetSectionGroup() unterstützt keine Parameter (unter Framework 3.5).

Stattdessen verwenden:

Configuration config = System.Configuration.ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); 
ServiceModelSectionGroup group = System.ServiceModel.Configuration.ServiceModelSectionGroup.GetSectionGroup(config); 

7

Dank der anderen Plakate dies ist die Funktion, die ich den URI eines benannten Endpunkt erhalten entwickelt. Es schafft auch eine Liste der Endpunkte in Gebrauch und welche tatsächliche Konfigurationsdatei verwendet wurde, bei der Fehlersuche:

Private Function GetEndpointAddress(name As String) As String 
    Debug.Print("--- GetEndpointAddress ---") 
    Dim address As String = "Unknown" 
    Dim appConfig As Configuration = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None) 
    Debug.Print("app.config: " & appConfig.FilePath) 
    Dim serviceModel As ServiceModelSectionGroup = ServiceModelSectionGroup.GetSectionGroup(appConfig) 
    Dim bindings As BindingsSection = serviceModel.Bindings 
    Dim endpoints As ChannelEndpointElementCollection = serviceModel.Client.Endpoints 
    For i As Integer = 0 To endpoints.Count - 1 
     Dim endpoint As ChannelEndpointElement = endpoints(i) 
     Debug.Print("Endpoint: " & endpoint.Name & " - " & endpoint.Address.ToString) 
     If endpoint.Name = name Then 
      address = endpoint.Address.ToString 
     End If 
    Next 
    Debug.Print("--- GetEndpointAddress ---") 
    Return address 
End Function