【问题标题】:How to programmatically change an endpoint's identity configuration?如何以编程方式更改端点的身份配置?
【发布时间】:2011-11-15 07:39:34
【问题描述】:

我正在尝试创建一个工具来以编程方式修改我的服务的 app.config 文件。代码是这样的,

string _configurationPath = @"D:\MyService.exe.config";
ExeConfigurationFileMap executionFileMap = new ExeConfigurationFileMap();
executionFileMap.ExeConfigFilename = _configurationPath;

System.Configuration.Configuration config = ConfigurationManager.OpenMappedExeConfiguration(executionFileMap, ConfigurationUserLevel.None);
ServiceModelSectionGroup serviceModeGroup = ServiceModelSectionGroup.GetSectionGroup(config);

foreach (ChannelEndpointElement endpoint in serviceModeGroup.Client.Endpoints)
{
    if (endpoint.Name == "WSHttpBinding_IMyService")
    {
        endpoint.Address = new Uri("http://localhost:8080/");
    }
}

config.SaveAs(@"D:\MyService.exe.config");

但是我在更改端点的身份时遇到了问题。

我想要类似的东西:

<identity>
     <userPrincipalName value="user@domain.com" />
</identity>

对于我的端点配置,但是当我尝试时:

endpoint.Identity = new IdentityElement(){
    UserPrincipalName = UserPrincipalNameElement() { Value = "user@domain.com" }
}

它失败是因为属性endpoint.IdentityidentityElement.UserPrincipalName 是只读的(我不知道为什么,因为 entity.Address 不是只读的)

有没有办法绕过这个限制并设置身份配置?

【问题讨论】:

    标签: .net wcf configuration app-config


    【解决方案1】:

    试试这样的...

    http://msdn.microsoft.com/en-us/library/bb628618.aspx

        ServiceEndpoint ep = myServiceHost.AddServiceEndpoint(
                    typeof(ICalculator),
                    new WSHttpBinding(),
                    String.Empty);
    EndpointAddress myEndpointAdd = new EndpointAddress(new Uri("http://localhost:8088/calc"),
         EndpointIdentity.CreateDnsIdentity("contoso.com"));
    ep.Address = myEndpointAdd;
    

    【讨论】:

    • 您好,我正在尝试修改并保存配置文件,而不是尝试修改 ServiceEndpoint 对象
    【解决方案2】:

    我认为框架中没有内置的方法,至少我没有看到任何简单但可能是错误的方法。

    我确实看到了另一个问题的答案https://stackoverflow.com/a/2068075/81251,它使用标准 XML 操作来更改端点地址。这是一个 hack,但它可能会做你想做的事。

    为了完整起见,以下是链接答案中的代码:

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

    【讨论】:

      【解决方案3】:

      对于任何正在寻找解决方案的人,我相信您可以通过以下方式实现它(这是上一个示例的一个小扩展):

          public void ChangeMyEndpointConfig(ChannelEndpointElement existingElement, ServiceModelSectionGroup grp, string identityValue)
          {
              EndpointAddress endpointAddress = new EndpointAddress(existingElement.Address, EndpointIdentity.CreateDnsIdentity(identityValue));
      
              var newElement = new ChannelEndpointElement(endpointAddress, existingElement.Contract)
              {
                  BehaviorConfiguration = existingElement.BehaviorConfiguration,
                  Binding = existingElement.Binding,
                  BindingConfiguration = existingElement.BindingConfiguration,
                  Name = existingElement.Name
                  // Set other values
              };
              grp.Client.Endpoints.Remove(existingElement);
              grp.Client.Endpoints.Add(newElement);
          }
      

      【讨论】:

        【解决方案4】:

        这被确认为有效。好痛……

        public static void ChangeClientEnpoint(string name, Uri newAddress)
            {
                System.Configuration.Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
                ServiceModelSectionGroup serviceModeGroup = ServiceModelSectionGroup.GetSectionGroup(config);
                ChannelEndpointElement existingElement = null;
                foreach (ChannelEndpointElement endpoint in serviceModeGroup.Client.Endpoints)
                {
                    if (endpoint.Name == "BasicHttpBinding_IMembershipService")
                    {
                        existingElement = endpoint;
                    }
                }
                EndpointAddress endpointAddress = new EndpointAddress(newAddress.ToString());
                var newElement = new ChannelEndpointElement(endpointAddress, existingElement.Contract)
                {
                    BehaviorConfiguration = existingElement.BehaviorConfiguration,
                    Binding = existingElement.Binding,
                    BindingConfiguration = existingElement.BindingConfiguration,
                    Name = existingElement.Name
                    // Set other values
                };
                serviceModeGroup.Client.Endpoints.Remove(existingElement);
                serviceModeGroup.Client.Endpoints.Add(newElement);
                config.Save();
                ConfigurationManager.RefreshSection("system.serviceModel/client");
            }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-09-29
          • 1970-01-01
          • 1970-01-01
          • 2010-11-03
          • 2013-12-23
          • 2017-04-09
          • 1970-01-01
          相关资源
          最近更新 更多