c# - IIS 中的 WCF,在工作组模式下使用 MSMQ

标签 c# wcf iis msmq

我一直在试用 MSMQ 和 WCF,但我似乎无法让它正常工作。通过使用 WCF 和服务引用,我已经让客户端(向队列发送消息)正常工作。执行此操作的代码或多或少是这样的:

static void Main(string[] args)
{
    var client = new MsmqServiceReference.MsmqContractClient();
    client.SendMessage("TEST");
    client.Close();
    Console.ReadKey();
}

其中 MsmqContractClient 是我添加服务引用时由 visual studio 生成的代理。 app.config 中的端点指向一个 msmqueue:

<client>
  <endpoint 
    address="net.msmq://localhost/private/MsmqService/MsmqService.svc"
    binding="netMsmqBinding"  
    bindingConfiguration="MsmqBindingNonTransactionalNoSecurity"
    contract="MsmqServiceReference.IMsmqContract" name="MsmqService" />
</client>

这有效,消息被发布到队列中。

现在我正试图让服务正常工作,但我不断收到此错误:

Binding validation failed because the binding's MsmqAuthenticationMode property is set to WindowsDomain but MSMQ is installed with Active Directory integration disabled. The channel factory or service host cannot be opened.

我尝试过的是:

  • 授予每个人对队列的完全访问权限(包括匿名登录)

  • 将应用配置为使用来自配置文件的特定绑定(bind):

    <bindings>
      <netMsmqBinding>
         <binding name="MsmqBindingNonTransactionalNoSecurity" 
                  deadLetterQueue="Custom" 
                  exactlyOnce="false">
           <security mode="None" />
         </binding>
      </netMsmqBinding>
    </bindings>
    
  • 我尝试在我自己的帐户和管理员帐户下运行 IIS (7) 中的应用程序池

让我感到困惑的是,它一直试图让我相信我正在尝试使用 WindowsDomain 身份验证来运行它。我说过我不想在安全模式设置为无的情况下这样做,对吧?

目前我的应用只是一个添加了 WCF 服务的 webforms asp.net 站点。

如果有人至少能为我指出正确的方向,我将不胜感激,因为我已经在这上面花费了太多时间。


似乎配置被忽略或覆盖了。完整的错误信息:

WebHost failed to process a request.
 Sender Information: System.ServiceModel.Activation.HostedHttpRequestAsyncResult/63721755
 Exception: System.ServiceModel.ServiceActivationException: The service '/MsmqService/MsmqService.svc' cannot be activated due to an exception during compilation.  The exception message is: Binding validation failed because the binding's MsmqAuthenticationMode property is set to WindowsDomain but MSMQ is installed with Active Directory integration disabled. The channel factory or service host cannot be opened.. ---> System.InvalidOperationException: Binding validation failed because the binding's MsmqAuthenticationMode property is set to WindowsDomain but MSMQ is installed with Active Directory integration disabled. The channel factory or service host cannot be opened.
   at System.ServiceModel.Channels.MsmqVerifier.VerifySecurity(MsmqTransportSecurity security, Nullable`1 useActiveDirectory)
   at System.ServiceModel.Channels.MsmqVerifier.VerifyReceiver(MsmqReceiveParameters receiveParameters, Uri listenUri)
   at System.ServiceModel.Channels.MsmqTransportBindingElement.BuildChannelListener[TChannel](BindingContext context)
   at System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener[TChannel]()
   at System.ServiceModel.Channels.MessageEncodingBindingElement.InternalBuildChannelListener[TChannel](BindingContext context)
   at System.ServiceModel.Channels.BinaryMessageEncodingBindingElement.BuildChannelListener[TChannel](BindingContext context)
   at System.ServiceModel.Channels.BindingContext.BuildInnerChannelListener[TChannel]()
   at System.ServiceModel.Channels.Binding.BuildChannelListener[TChannel](Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, BindingParameterCollection parameters)
   at System.ServiceModel.Description.DispatcherBuilder.MaybeCreateListener(Boolean actuallyCreate, Type[] supportedChannels, Binding binding, BindingParameterCollection parameters, Uri listenUriBaseAddress, String listenUriRelativeAddress, ListenUriMode listenUriMode, ServiceThrottle throttle, IChannelListener& result, Boolean supportContextSession)
   at System.ServiceModel.Description.DispatcherBuilder.BuildChannelListener(StuffPerListenUriInfo stuff, ServiceHostBase serviceHost, Uri listenUri, ListenUriMode listenUriMode, Boolean supportContextSession, IChannelListener& result)
   at System.ServiceModel.Description.DispatcherBuilder.InitializeServiceHost(ServiceDescription description, ServiceHostBase serviceHost)
   at System.ServiceModel.ServiceHostBase.InitializeRuntime()
   at System.ServiceModel.ServiceHostBase.OnBeginOpen()
   at System.ServiceModel.ServiceHostBase.OnOpen(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Open()
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.ActivateService(String normalizedVirtualPath)
   at System.ServiceModel.ServiceHostingEnvironment.HostingManager.EnsureServiceAvailable(String normalizedVirtualPath)
   --- End of inner exception stack trace ---
   at System.Runtime.AsyncResult.End[TAsyncResult](IAsyncResult result)
   at System.ServiceModel.Activation.HostedHttpRequestAsyncResult.End(IAsyncResult result)
 Process Name: w3wp
 Process ID: 5660

我试着弄清楚使用 Reflector 会发生什么,但它似乎只是以某种方式将 MsmqTransportBindingElement 传递到 channel 构建过程中,确信它必须使用 WindowsDomain 作为安全措施。但是,我在我的配置文件中将安全设置为无。关于这种覆盖行为的来源有什么想法吗?


解决方案:

一方面觉得自己很笨,另一方面又觉得还有进步的空间。 简短的版本是我弄乱了服务元素的“名称”属性中的值:

<services>
  <service name="WcfService.MsmqService">
    <!--        <endpoint binding="mexHttpBinding" contract="IMetadataExchange" />-->
    <endpoint name="msmq" 
            address="net.msmq://localhost/private/MsmqService/MsmqService.svc"
            binding="netMsmqBinding" 
            bindingConfiguration="NoSecurity"
            contract="WcfService.IMsmqContract" />
  </service>
</services>

名称与我的客户端相同,但是,客户端具有由 visual studio 生成的绑定(bind)。我给了它一个不同的名称 (MsmqService),因此名称值为“MsmqService.MsmqService”。

让我感到困扰的是,我没有收到任何关于我正在配置不存在的服务的警告,也没有收到任何指示我正在使用该服务的默认配置。如果框架至少在我使用默认设置的某处生成警告,或者打开某种形式的严格模式的选项,那将是非常好的。无论哪种方式,感谢您的所有意见,我将再用头撞墙几次。

是的,您现在可以指指点点并大笑 ;-)

最佳答案

尝试这些设置... useActiveDirectory 默认情况下应该是 false,但请尝试一下。身份验证模式在传输本身上设置,因此 msmqAuthenticationMode 应设置为“无”。 msmqProtectionLevelclientCredentialType 听起来很相关,所以我也把它们放在那里了
:)


<bindings>
  <netMsmqBinding>
     <binding name="MsmqBindingNonTransactionalNoSecurity" 
          deadLetterQueue="Custom"
          useActiveDirectory="false" 
          exactlyOnce="false">
       <security mode="None">
         <transport 
            msmqAuthenticationMode="None"
            msmqProtectionLevel="None"
            clientCredentialType="None"/>
       </security>
     </binding>
  </netMsmqBinding>
</bindings>

我会担心删除所有安全性,但是...如果您在域中,则应安装带有 Active Directory Integration 的 MSMQ,或使用 Workgroup 方法来保护消息。

另外,不要忘记,服务器和客户端的设置必须匹配。

HTH,
詹姆斯

抱歉持续更新,今天我对细节的关注度似乎有点低
:P

关于c# - IIS 中的 WCF,在工作组模式下使用 MSMQ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4493239/

相关文章:

asp.net - .Net框架: exception in w3wp. exe

c# - 如何读取没有 LINES 属性的 xaml 文本框的最后一行

c# - 服务引用(VS2013)在命名空间中使用元素名称声明了多个故障

.net - 在无状态 REST Web 服务环境中实现验证码

无法从公共(public) IP/cloudapp.net 域访问 Azure VM IIS

iis - 确定 AZURE 上的 W3SCV 名称

c# - 检查 web 表单是否在 javascript 中关闭/刷新

c# - 解析 XML 响应

c# - 如何在 C# 中使用可选参数构建 Web 服务/Web API

.net - Spring.net WCF 服务和多线程 : manage count thread for exec WCF method