Загрузка System.ServiceModel с помощью ConfigurationManager


55

Используя C# .NET 3.5 и WCF, я пытаюсь выписать часть конфигурации WCF в клиентском приложении (имя сервера, к которому клиент подключается).

Очевидным способом является использование ConfigurationManager для загрузки раздела конфигурации и записи необходимых мне данных.

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

Появляется, чтобы всегда возвращать null.

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

Работает отлично.

Раздел конфигурации присутствует в App.config, но по какой-то причине ConfigurationManager отказывается загрузить раздел system.ServiceModel.

Я хочу, чтобы вручную загрузить файл xxx.exe.config и использовать XPath, но если мне придется прибегнуть к тому, что я сделаю. Просто кажется, что-то вроде взлома.

Любые предложения?

45

Элемент <system.serviceModel> относится к разделу конфигурации group, а не к разделу. Вам нужно будет использовать System.ServiceModel.Configuration.ServiceModelSectionGroup.GetSectionGroup(), чтобы получить всю группу.


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

Появляется хорошо работать.

+1

запутанная линия для endpointCollection = clientSection.ElementInformation.Properties [string.Empty] .Value в ChannelEndpointElementCollection; должно быть упрощено до clientSection.Endpoints; 23 окт. 132013-10-23 01:56:19


14

Это то, что я искал благодаря @marxidad для указателя.

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() не поддерживает никаких параметров (в рамках 3.5).

Вместо этого используйте:

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

7

Благодаря другим афиш это функция, которую я разработал, чтобы получить URI именованного конечной точки. Он также создает список конечных точек в использовании и которые фактический конфигурационный файл в настоящее время используется при отладке:

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