C# 单独程序集中的WCF协定-如何将其用作端点协定?
为了解决这个问题,我搜索并浪费了一整天的时间,想尽一切办法来解决这个问题:我构建了我的第一个WCF服务,并认为在IIS中托管它会很酷。这是一项长期运行的服务,所以这是不可能的。此后,我在解决方案中添加了另一个项目来托管WCF服务,引用了WCF项目,并且在尝试从代码托管时遇到了不断的困难。 我在很大程度上遵循了关于实现主机的指导,并针对我的具体情况做了一些小的调整 当前的挑战只是获取托管项目的App.config中定义的服务端点。它无法将“端点”的“协定”属性解析为我的WCF服务协定 WCF组件C# 单独程序集中的WCF协定-如何将其用作端点协定?,c#,.net,wcf,C#,.net,Wcf,为了解决这个问题,我搜索并浪费了一整天的时间,想尽一切办法来解决这个问题:我构建了我的第一个WCF服务,并认为在IIS中托管它会很酷。这是一项长期运行的服务,所以这是不可能的。此后,我在解决方案中添加了另一个项目来托管WCF服务,引用了WCF项目,并且在尝试从代码托管时遇到了不断的困难。 我在很大程度上遵循了关于实现主机的指导,并针对我的具体情况做了一些小的调整 当前的挑战只是获取托管项目的App.config中定义的服务端点。它无法将“端点”的“协定”属性解析为我的WCF服务协定 WCF组件
namespace WcfFoldingService
{
[ServiceContract(SessionMode=SessionMode.Required, CallbackContract=typeof(IFoldingUpdaterClientContract))]
public interface IFoldingUpdaterServiceBehavior
{
[OperationContract(IsOneWay = false, IsInitiating = true)]
void Subscribe();
[OperationContract(IsOneWay = false, IsTerminating = true)]
void Unsubscribe();
[OperationContract(IsOneWay = true)]
void PublishSomeOperation();
}
public interface IFoldingUpdaterClientContract
{
[OperationContract(IsOneWay = true)]
void SomeOperation();
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, ConcurrencyMode=ConcurrencyMode.Single)]
public class FoldingUpdaterService : IFoldingUpdaterServiceBehavior
{
// Omitted for brevity, but complete implementation exists.
}
}
/WCF组件
namespace WcfFoldingService
{
[ServiceContract(SessionMode=SessionMode.Required, CallbackContract=typeof(IFoldingUpdaterClientContract))]
public interface IFoldingUpdaterServiceBehavior
{
[OperationContract(IsOneWay = false, IsInitiating = true)]
void Subscribe();
[OperationContract(IsOneWay = false, IsTerminating = true)]
void Unsubscribe();
[OperationContract(IsOneWay = true)]
void PublishSomeOperation();
}
public interface IFoldingUpdaterClientContract
{
[OperationContract(IsOneWay = true)]
void SomeOperation();
}
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerSession, ConcurrencyMode=ConcurrencyMode.Single)]
public class FoldingUpdaterService : IFoldingUpdaterServiceBehavior
{
// Omitted for brevity, but complete implementation exists.
}
}
宿主程序集
App.config
<system.serviceModel>
<services>
<service name="WcfFoldingService.FoldingUpdaterService" behaviorConfiguration="httpServiceBehavior">
<endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="ServiceBindingConfiguration" contract="WcfFoldingService.IFoldingUpdaterServiceBehavior"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<protocolMapping>
<add scheme="http" binding="wsDualHttpBinding" bindingConfiguration="ServiceBindingConfiguration"/>
</protocolMapping>
<bindings>
<wsDualHttpBinding>
<binding name="ServiceBindingConfiguration">
<reliableSession ordered="true"/>
<security mode="None"/>
</binding>
</wsDualHttpBinding>
</bindings>
<behaviors>
<serviceBehaviors>
<behavior name="httpServiceBehavior">
<serviceMetadata httpGetEnabled="True"/>
<serviceDebug includeExceptionDetailInFaults="False"/>
<serviceThrottling maxConcurrentCalls="1000" maxConcurrentInstances="100" maxConcurrentSessions="100"/>
<sendMessageChannelCache allowUnsafeCaching="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
Message:
The 'contract' attribute is invalid - The value 'WcfFoldingService.IFoldingUpdaterServiceBehavior' is invalid according to its datatype 'serviceContractType' - The Enumeration constraint failed.
我被难住了。谷歌提供的相关链接很少,它们大多与我没有遇到的其他配置问题有关。WCF程序集被引用,我使用的是完全限定名,我甚至尝试使用ConfigurationName属性,以防出现名称空间冲突。我是WCF的新手,所以我希望这是一个明显的问题
编辑:
我现在使用的是编程配置,而不是App.config XML。最重要的语句是ContractDescription.GetContract(serviceType)
,因为即使是new ContractDescription(“FullNamespace.IContract”)
也与XML配置一样失败。serviceType的FullName属性的Type对象与我的“FullNamespace.IContract”完全相同。我怀疑在代码中没有对程序集进行硬引用的情况下,程序集可能无法加载,但目前我无法确定。目前,这种方法可以很好地发挥作用:
using (var host = new ServiceHost(typeof(FoldingUpdaterService), baseAddress))
{
var serviceType = typeof (IFoldingUpdaterServiceBehavior);
var serviceContract = ContractDescription.GetContract(serviceType);
var foldingEndpoint = new ServiceEndpoint(serviceContract)
{
Binding = new WSDualHttpBinding()
Address = new EndpointAddress(new Properties.Settings().WcfUpdaterServiceAddress)
};
host.Description.Endpoints.Add(foldingEndpoint);
[...]
自托管应用程序将需要
标记内的
标记:
<system.serviceModel>
<services>
<service name="WcfFoldingService.FoldingUpdaterService" behaviorConfiguration="httpServiceBehavior">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/Services/"/>
</baseAddresses>
</host>
<endpoint address="" binding="wsDualHttpBinding" bindingConfiguration="ServiceBindingConfiguration" contract="WcfFoldingService.IFoldingUpdaterServiceBehavior"/>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
确保您在主机中引用了服务应用程序我不知道这是否仍然是您的问题,但最近偶然发现了相同的问题,可能会有所帮助
指定服务名称时,还必须使用名称空间。假设您的名称空间是myhost
,那么正确的条目是
这同样适用于合同。这是一个老问题,但如果有人有同样的问题,这对我来说是有效的:
尝试关闭Visual Studio并删除与解决方案文件(.sln)位于同一目录下的.suo文件。这将重置编辑器缓存。在我将服务合约文件移动到另一个程序集并且缓存仍然引用旧位置后,我遇到了相同的问题。我用VS2012创建的解决方案包含几个.NET 4.0项目。我切换到VS2013,当我添加一个新的WCF库项目时,它是用.NET4.5创建的。将新项目重置为.NET 4.0解决了我的问题。是否尝试使用Microsoft(R)服务配置编辑器?(工具->WCF配置…)我还没有试过。有趣的是,服务配置编辑器生成的端点配置与我所做的完全相同——contract和all。端点仍然无法验证,并显示相同的枚举约束冲突警告消息。感谢您的输入;我确实需要,但这个问题涉及到另一个问题。@Kenny:我复制并粘贴了你的代码到一个新的解决方案中。WCF应用程序和控制台应用程序作为引用WCF项目的服务主机。成功了!我无法重现你提到的错误。我使用了Visual Studio 2012。我也在使用2012!我不确定它为什么难以解决合同问题。我刚刚推出了一个新的控制台应用程序主机来尝试编程配置,而不是XML配置,并且我必须使用类型方法来获得合同。真奇怪。。。我会用密码回答。谢谢你在这方面的努力;我仍然不确定XML配置的问题是什么,但至少我现在有了工作的角度!您的评论修复了我的问题,但实际上是因为我试图在VS的wcfservicehost中托管一个32位服务。删除suo会将其恢复为默认的AnyCPU。有关32位的讨论,请参阅。