单独程序集中的WCF契约-如何将其用作端点契约

本文关键字:契约 端点 程序集 程序 集中 WCF 单独 | 更新日期: 2023-09-27 18:07:57

我已经搜索并浪费了一整天的时间来尝试我能想到的或找到的所有方法来解决这个问题:我构建了我的第一个WCF服务,并认为将其托管在IIS中会很酷。这是一个长期运行的服务,所以这是不允许的。此后,我在我的解决方案中添加了另一个项目来托管WCF服务,引用了WCF项目,并且遇到了试图从代码托管的不断挣扎。我在很大程度上遵循http://msdn.microsoft.com/en-us/library/ms733069.aspx实现主机的指导,并根据我的具体情况进行了轻微的调整。

当前的挑战是简单地获得在托管项目的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组装

/

举办大会

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对象与我的"fullnamspace . 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);
    [...]

单独程序集中的WCF契约-如何将其用作端点契约

这是一个老问题,但如果有人有同样的问题,这对我有用:尝试关闭Visual Studio并删除与解决方案文件(.sln)位于同一目录下的. so文件。这将重置编辑器缓存。在将服务契约文件移动到不同的程序集后,我遇到了同样的问题,缓存仍然引用旧位置。

自托管应用程序将需要<host>标记在<service>标记内:

<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>

我不知道这对你来说是否仍然是一个问题,但最近偶然发现了同样的问题,它可能会有所帮助。

指定Service Name时,也必须使用Namespace。比如你的命名空间是myhost那么正确的条目应该是。

<service name="myhost.WcfFoldingService.FoldingUpdaterService"...>

这同样适用于合同

我的解决方案是用VS2012创建的,包含了几个。net 4.0项目。我切换到VS2013,当我添加一个新的WCF库项目时,它是用。net 4.5创建的。重置新项目到。net 4.0解决了我的问题。

确保在主机中引用了服务应用程序