使用Visual Studio 2013 Premium。
目标:我在web.config中定义了多个WCF服务。为了使web.config文件可读并使添加服务更简单,我想使用VS2013的XML转换为我的开发/生产环境的每个服务定义添加一些样板元素。
问题:我有多个<service>
代码,但只有第一个正确转换。
这是我的Web.Config的简化版本,其中定义了两个服务:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<services>
<service name="AppName.AccountManagerService">
<endpoint address="AccountManagerService" binding="netTcpBinding"
bindingConfiguration="" contract="Shared.Contracts.IAccountManagerService" />
</service>
<service name="AppName.TicketManagerService">
<endpoint address="TicketManagerService" binding="netTcpBinding"
bindingConfiguration="" contract="Shared.Contracts.ITicketManagerService" />
</service>
</services>
</configuration>
我想创建一个元数据交换端点,并为每个<service>
标记做一些其他事情(未显示)。
这是一个简化的Web.Debug.Config,仅显示MetadataExchange端点:
<?xml version="1.0" encoding="utf-8"?>
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
<system.serviceModel>
<services>
<service xdt:Locator="XPath(/configuration/system.serviceModel/services/service)">
<endpoint kind="mexEndpoint"
address="mex"
xdt:Transform="Insert()"
/>
</service>
</services>
</system.serviceModel>
</configuration>
我明白了:
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<services>
<service name="AppName.AccountManagerService">
<endpoint address="AccountManagerService" binding="netTcpBinding"
bindingConfiguration="" contract="Shared.Contracts.IAccountManagerService" />
<!-- Yay! -->
<endpoint kind="mexEndpoint"
address="mex"
/>
</service>
<service name="AppName.TicketManagerService">
<endpoint address="TicketManagerService" binding="netTcpBinding"
bindingConfiguration="" contract="Shared.Contracts.ITicketManagerService" />
<!-- Hey, where's the endpoint tag for this one? -->
</service>
</services>
</configuration>
我在以下XPath
属性的xdt:Locator
参数中尝试了这些变体:
1. /configuration/system.serviceModel/services/service
2. /configuration/system.serviceModel/services//service
3. //service
所有这些都只转换 第一个<service>
部分。
我已尝试在xdt:Locator
标记等上添加<endpoint>
属性无效。
我有多个XPath可视化工具和工具,当与上面的XPath#1一起使用时,它们都匹配两个 <service>
标记。此外,此错误发生在“预览转换”和Web部署工具预览中。
我做错了什么?
(我的解决方法是,在这一点上,将Mex端点和其余的调试内容包含在我原来的Web.Config中,然后使用“RemoveAll()”将其删除,但这使我的Web.Config真的混乱,难以阅读。)
答案 0 :(得分:1)
我最近遇到了这个问题,事实证明它不受支持。
我的工作是添加自定义转换,并使用它而不是Insert。它们的实现问题是默认的Insert只修改第一个值(即使XPath表达式确实检索了一个列表)。
可以在此处找到XDT源代码:http://xdt.codeplex.com/
我遇到的文章让我朝着正确的方向前进:http://blog.appharbor.com/2012/07/27/custom-web-config-transforms-and-merges
我所做的是在他们的来源中添加一个新类,并且能够完全达到你想要的目标。
internal class InsertMultiple : Transform
{
public InsertMultiple()
{
//this is the line that allows it to apply the transform for all nodes
//that were located with your XPath expression.
ApplyTransformToAllTargetNodes = true;
}
protected override void Apply()
{
CommonErrors.ExpectNoArguments(Log, TransformNameShort, ArgumentString);
TargetNode.AppendChild(TransformNode);
Log.LogMessage(MessageType.Verbose, SR.XMLTRANSFORMATION_TransformMessageInsert, TransformNode.Name);
}
}