wcf - 在运行时更改 WSDL EndPointAddress 的地址/端口?

标签 wcf web-services wsdl app-config

所以我目前在我的解决方案中添加了 2 个 WSDL 作为服务引用。它们在我的 app.config 文件中看起来像这样(我删除了“绑定(bind)”字段,因为它无趣):

<system.serviceModel>
  <client>
    <endpoint address="http://localhost:8080/query-service/jse" binding="basicHttpBinding" bindingConfiguration="QueryBinding" contract="QueryService.Query" name="QueryPort" />
    <endpoint address="http://localhost:8080/dataimport-service/jse" binding="basicHttpBinding" bindingConfiguration="DataImportBinding" contract="DataService.DataImport" name="DataImportPort" />
  </client>   
</system.serviceModel>

当我使用 WSDL 时,它看起来像这样:
using (DataService.DataClient dClient = new DataService.DataClient())
{
  DataService.importTask impt = new DataService.importTask();
  impt.String_1 = "someData";
  DataService.importResponse imptr = dClient.importTask(impt);
}

在“使用”语句中,实例化 DataClient 对象时,我有 5 个可用的构造函数。在这种情况下,我使用默认构造函数:
   new DataService.DataClient()

它使用内置的端点地址字符串,我假设它是从 app.config 中提取的。但我希望应用程序的用户可以选择更改此值。

1)以编程方式获取此字符串的最佳/最简单方法是什么?

2)然后,一旦我允许用户编辑和测试该值,我应该将它存储在哪里?

我更喜欢将它存储在一个地方(如 app.config 或等效项),这样就无需检查该值是否存在以及我是否应该使用备用构造函数。 (希望保持我的代码紧凑,你知道吗?)

有任何想法吗?建议?

编辑

也许我也应该询问这些备用构造函数。

例如,其中一个看起来像这样:
   new DataService.DataClient(string endPointConfigurationName, 
                              string remoteAddress)

可以为“endPointConfigurationName”和“remoteAddress”传递哪些值?

编辑2

在这里回答我自己的问题,“endPointConfigurationName”似乎与 app.config XML 中的“名称”相同,并且“remoteAddress”的格式与 app.config XML 中的“端点地址”相同。

还!关于获取 EndPointAddresses 的第一个问题的答案如下:
ClientSection clSection =
   ConfigurationManager.GetSection("system.serviceModel/client") as ClientSection;

ChannelEndpointElementCollection endpointCollection =
   clSection.ElementInformation.Properties[string.Empty].Value as ChannelEndpointElementCollection;

Dictionary<string, string> nameAddressDictionary = 
   new Dictionary<string, string>();

foreach (ChannelEndpointElement endpointElement in endpointCollection)
{
   nameAddressDictionary.Add(endpointElement.Name, 
                             endpointElement.Address.ToString());
}

编辑3

好的,我想我已经弄清楚了我的问题的第二部分(因此,完整的解决方案)。我在另一个网站上找到了这个,并对其进行了修改以满足我的需要:
Configuration configuration; 
ServiceModelSectionGroup serviceModelSectionGroup;
ClientSection clientSection;

configuration = 
    ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
serviceModelSectionGroup = 
    ServiceModelSectionGroup.GetSectionGroup(configuration);
clientSection = serviceModelSectionGroup.Client;

foreach (ChannelEndpointElement endPt in clientSection.Endpoints)
{
  MessageBox.Show(endPt.Name + " = " + endPt.Address);
}
configuration.Save();

使用此代码,我们可以访问 clientSection.Endpoints 并且可以访问和更改所有成员属性,例如“地址”。然后当我们完成更改它们时,我们可以执行 configuration.Save() 并将所有值写入用户文件。

现在这是问题所在。在 Debug模式下,“configuration.save()”似乎并没有真正将你的值从执行到执行,但是在正常运行应用程序时(在 Debug模式之外),这些值仍然存在。 (这很好。)所以这是唯一的警告。

EDIT4

还有一个警告。对 WSDL 所做的更改在运行时不会生效。需要重新启动应用程序才能将用户配置文件值重新读入内存(显然。)

我可能感兴趣的唯一另一件事是找到一种方法(一旦更改了值)将值恢复为默认值。当然,您可能可以删除用户文件,但这会删除所有自定义设置。

有任何想法吗?

EDIT5

我认为依赖注入(inject)在这里可能是完美的,但需要更多地研究它......

编辑 6

我没有评论权限,但你需要运行
ConfigurationManager.RefreshSection("client");

更新缓存,以便立即发生更改。

最佳答案

如果您使用的是 Microsoft 添加网络引用 要创建您的服务引用,那么我认为您可能无法以编程方式更改连接。即使您确实更改了自动生成的代码,只要您执行了 更新服务引用 它会被覆盖。

最好的办法是从 Microsoft 自动生成的代码开始编写自己的 WCF 类。这并不难,并且提供了很多灵 active /可扩展性。

Here's an excellent article在这个问题上。

至于存储自定义地址,这取决于您的应用程序是 Silverlight、Windows 还是 Web 应用程序。我个人的选择是数据库。

关于wcf - 在运行时更改 WSDL EndPointAddress 的地址/端口?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2670551/

相关文章:

c# - 如何在 C# 中使用 WCF REST 服务?

php - 无法在服务器中插入信息,但我可以作为本地主机

java - 调用Web服务客户端时的并发

java |网络服务错误

wcf - WCF Rest 服务的 SSL 实现

c# - 使用 WCF Web 服务时获取 System.ServiceModel.ProtocolException

java - 在 JAVA 中使用基于安全 SOAP 的 Web 服务时出错

soap - 谁在使用XML Schema 1.1版本?哪些解析器版本支持它?等等

java - 使用 Java WSDL、Enum 和 Boolean 属性的 C# 不会根据请求发送

c# - 如何从正在运行的 WCF 服务中导出元数据