C#运行时向App.Config添加system.serviceModel节点可行吗?
可行的实现方式
当然有靠谱的办法来实现运行时向app.config添加指定的<system.serviceModel>配置段!下面我给你两种常用的方案,你可以根据自己的需求选择:
方法一:通过Configuration API动态修改配置文件
这种方式会直接修改app.config文件(如果需要永久保存的话),也可以只在当前进程内存中生效。你需要用到System.Configuration和System.ServiceModel.Configuration命名空间下的API:
using System.Configuration; using System.ServiceModel.Configuration; // 1. 获取当前应用的配置对象 Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); // 2. 获取或创建system.serviceModel节组 ServiceModelSectionGroup serviceModelGroup = ServiceModelSectionGroup.GetSectionGroup(config); if (serviceModelGroup == null) { serviceModelGroup = new ServiceModelSectionGroup(); config.SectionGroups.Add("system.serviceModel", serviceModelGroup); } // 3. 添加BasicHttpBindings配置 BasicHttpBindingCollectionElement basicHttpBindings = serviceModelGroup.Bindings.BasicHttpBinding; // 添加第一个绑定:InvioTelematicoSS730pMtomPortBinding if (!basicHttpBindings.Bindings.ContainsKey("InvioTelematicoSS730pMtomPortBinding")) { BasicHttpBindingElement mtomBinding = new BasicHttpBindingElement("InvioTelematicoSS730pMtomPortBinding"); mtomBinding.MessageEncoding = WSMessageEncoding.Mtom; mtomBinding.Security.Mode = BasicHttpSecurityMode.Transport; basicHttpBindings.Bindings.Add(mtomBinding); } // 添加第二个绑定:RicevutaPdf730PortBinding if (!basicHttpBindings.Bindings.ContainsKey("RicevutaPdf730PortBinding")) { BasicHttpBindingElement pdfBinding = new BasicHttpBindingElement("RicevutaPdf730PortBinding"); pdfBinding.Security.Mode = BasicHttpSecurityMode.Transport; basicHttpBindings.Bindings.Add(pdfBinding); } // 添加第三个绑定:RicevutaPdf730PortBinding1 if (!basicHttpBindings.Bindings.ContainsKey("RicevutaPdf730PortBinding1")) { BasicHttpBindingElement emptyBinding = new BasicHttpBindingElement("RicevutaPdf730PortBinding1"); basicHttpBindings.Bindings.Add(emptyBinding); } // 4. 添加Client Endpoints配置 ClientSection clientSection = serviceModelGroup.Client; // 第一个端点:InvioTelematicoSS730pMtomPort if (!clientSection.Endpoints.ContainsKey("InvioTelematicoSS730pMtomPort")) { ChannelEndpointElement mtomEndpoint = new ChannelEndpointElement(); mtomEndpoint.Address = new Uri("http://localhost:9080/InvioTelematicoSS730pMtomWeb/InvioTelematicoSS730pMtomPort"); mtomEndpoint.Binding = "basicHttpBinding"; mtomEndpoint.BindingConfiguration = "InvioTelematicoSS730pMtomPortBinding"; mtomEndpoint.Contract = "InvioFlussi730.InvioTelematicoSS730pMtom"; mtomEndpoint.Name = "InvioTelematicoSS730pMtomPort"; clientSection.Endpoints.Add(mtomEndpoint); } // 第二个端点:RicevutaPdf730Port if (!clientSection.Endpoints.ContainsKey("RicevutaPdf730Port")) { ChannelEndpointElement pdfEndpoint = new ChannelEndpointElement(); pdfEndpoint.Address = new Uri("https://invioSS730pTest.sanita.finanze.it/Ricevute730ServiceWeb/ricevutePdf"); pdfEndpoint.Binding = "basicHttpBinding"; pdfEndpoint.BindingConfiguration = "RicevutaPdf730PortBinding"; pdfEndpoint.Contract = "ServiceReference1.RicevutaPdf730"; pdfEndpoint.Name = "RicevutaPdf730Port"; clientSection.Endpoints.Add(pdfEndpoint); } // 5. 保存配置(可选:如果需要永久写入文件的话) try { config.Save(ConfigurationSaveMode.Modified); ConfigurationManager.RefreshSection("system.serviceModel"); Console.WriteLine("配置已成功添加并保存到app.config!"); } catch (ConfigurationErrorsException ex) { Console.WriteLine($"保存配置时遇到错误:{ex.Message}"); }
方法二:直接在代码中构建绑定和客户端(无需修改配置文件)
如果你不想修改app.config文件,或者担心权限问题(比如程序安装在受保护目录),可以直接在代码中创建绑定和ChannelFactory,完全跳过配置文件:
using System.ServiceModel; using System.ServiceModel.Channels; // 构建第一个服务的绑定和客户端 var mtomBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport); mtomBinding.MessageEncoding = WSMessageEncoding.Mtom; var mtomEndpoint = new EndpointAddress("http://localhost:9080/InvioTelematicoSS730pMtomWeb/InvioTelematicoSS730pMtomPort"); var mtomFactory = new ChannelFactory<InvioFlussi730.InvioTelematicoSS730pMtom>(mtomBinding, mtomEndpoint); InvioFlussi730.InvioTelematicoSS730pMtom mtomClient = mtomFactory.CreateChannel(); // 使用客户端调用服务... // mtomClient.YourServiceMethod(); // 构建第二个服务的绑定和客户端 var pdfBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport); var pdfEndpoint = new EndpointAddress("https://invioSS730pTest.sanita.finanze.it/Ricevute730ServiceWeb/ricevutePdf"); var pdfFactory = new ChannelFactory<ServiceReference1.RicevutaPdf730>(pdfBinding, pdfEndpoint); ServiceReference1.RicevutaPdf730 pdfClient = pdfFactory.CreateChannel(); // 使用客户端调用服务... // pdfClient.YourPdfServiceMethod();
关键注意事项
- 权限问题:如果选择方法一保存配置到文件,若程序安装在
Program Files等受保护目录,需要管理员权限才能写入,否则会抛出异常。如果不需要永久保存,删掉config.Save相关代码即可,修改只会在当前进程生效。 - 重复添加:代码中加入了
ContainsKey检查,避免重复添加同名的绑定或端点,防止配置冲突。 - Web应用适配:如果是ASP.NET Web应用,只需把
ConfigurationManager.OpenExeConfiguration换成WebConfigurationManager.OpenWebConfiguration("~")即可。
内容的提问来源于stack exchange,提问作者Stefano Aquila
相关产品推荐
相关产品推荐

