WCF;温莎城堡-看起来你忘了

本文关键字:看起来 忘了 城堡 WCF | 更新日期: 2023-09-27 18:27:28

我们最近开始迁移到温莎城堡,在运行WCF服务时遇到了一些问题。这是一个常规的windows服务NOT HOSTED IN IIS,我们在其中提供SSL材料并使用自定义X509CertificateValidator来验证客户端提供的证书。

下面是我用来创建WCF服务的代码。它位于引用它的WCF服务的单独项目中。

public IWindsorContainer RegisterService<T,K>(
            IServiceBehavior customBehavior, 
            Action<ServiceHost> onCreate = null,
            Action<ServiceHost> onOpen = null, 
            Action<ServiceHost> onClose = null, 
            Action<ServiceHost> onFault = null) where T : class where K : T
        {
            var facility = this.AddFacility<WcfFacility>(f => f.CloseTimeout = TimeSpan.Zero);
            var serviceModel = new DefaultServiceModel()
                .OnCreated(onCreate)
                .OnOpened(onOpen)
                .OnClosed(onClose)
                .OnFaulted(onFault);
            var service = Component.For<T>()
                    .ImplementedBy<K>()
                    .AsWcfService<T>(serviceModel)
                    .LifestylePerWcfOperation<T>();
            if (customBehavior != null)
                facility.Register(Component.For<IServiceBehavior>().Instance(customBehavior));
            facility.Register(service);
            return facility;
        }

服务按预期启动(我可以使用chrome导航到服务,没有任何问题),服务正在呈现和验证SSL材料(即,命中自定义验证器),但之后,客户端在FaultException:中获得此信息

Looks like you forgot to register the http module Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule
To fix this add
<add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
to the <httpModules> section on your web.config.
If you plan running on IIS in Integrated Pipeline mode, you also need to add the module to the <modules> section under <system.webServer>.
Alternatively make sure you have Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35 assembly in your GAC (it is installed by ASP.NET MVC3 or WebMatrix) and Windsor will be able to register the module automatically without having to add anything to the config file.

下面是我的App.Config的一大块,我试图将模块放置在通过谷歌和一些猜测建议的所有区域:

...
<system.web>
    <httpModules>
      <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
    </httpModules>
    <membership defaultProvider="ClientAuthenticationMembershipProvider">
      <providers>
        <add name="ClientAuthenticationMembershipProvider" type="System.Web.ClientServices.Providers.ClientFormsAuthenticationMembershipProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" />
      </providers>
    </membership>
    <roleManager defaultProvider="ClientRoleProvider" enabled="true">
      <providers>
        <add name="ClientRoleProvider" type="System.Web.ClientServices.Providers.ClientRoleProvider, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" serviceUri="" cacheTimeout="86400" />
      </providers>
    </roleManager>
  </system.web>
  <system.webServer>
    <modules>
      <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
    </modules>
    <handlers>
      <add name="PerRequestLifestyle" verb="*" path="*.castle" preCondition="managedHandler" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Microkernel"/>
    </handlers>
  </system.webServer>
  <system.serviceModel>
    <extensions>
      <endpointExtensions>
        <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
      </endpointExtensions>
      <bindingExtensions>
        <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
      </bindingExtensions>
      <behaviorExtensions>
        <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
      </behaviorExtensions>
      <bindingElementExtensions>
        <add name="PerRequestLifestyle" type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor" />
      </bindingElementExtensions>
    </extensions>
...

我几乎没有主意。有人知道可能是什么原因吗?如果没有,有人能解释一下我犯的错误吗?任何帮助都将不胜感激!

WCF;温莎城堡-看起来你忘了

我再次回答我自己的问题(发帖后的第二天,哦,亲爱的):p

这个错误消息被抛出到这里(感谢上帝的开源!):

https://github.com/castleproject/Windsor/blob/016730de012f15985410fb33e2eb907690fe5a28/src/Castle.Windsor/MicroKernel/Lifestyle/PerWebRequestLifestyleModule.cs

tldr-见下文:

public class PerWebRequestLifestyleModule : IHttpModule
{
    ...
    private static void EnsureInitialized()
        {
            if (initialized)
            {
                return;
            }
            var message = new StringBuilder();
            message.AppendLine("Looks like you forgot to register the http module " + typeof(PerWebRequestLifestyleModule).FullName);
            message.AppendLine("To fix this add");
            message.AppendLine("<add name='"PerRequestLifestyle'" type='"Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule, Castle.Windsor'" />");
            message.AppendLine("to the <httpModules> section on your web.config.");
            if (HttpRuntime.UsingIntegratedPipeline)
            {
                message.AppendLine(
                    "Windsor also detected you're running IIS in Integrated Pipeline mode. This means that you also need to add the module to the <modules> section under <system.webServer>.");
            }
            else
            {
                message.AppendLine(
                    "If you plan running on IIS in Integrated Pipeline mode, you also need to add the module to the <modules> section under <system.webServer>.");
            }
#if !DOTNET35
            message.AppendLine("Alternatively make sure you have " + PerWebRequestLifestyleModuleRegistration.MicrosoftWebInfrastructureDll +
                               " assembly in your GAC (it is installed by ASP.NET MVC3 or WebMatrix) and Windsor will be able to register the module automatically without having to add anything to the config file.");
#endif
            throw new ComponentResolutionException(message.ToString());
        }
    ...
}

由此,我很快发现问题是PerWebRequestLifestyleModule没有初始化,这对我来说没问题,因为我不需要它来提供此服务!

进一步研究我自己的代码,我为该服务加载的一些存储库被设置为使用LifestylePerWebRequest,当它们在我们的网络控制台中使用时,宾果!

在将它们调整为其他东西(在本例中为"LifestylePerWcfOperation")后,一切都很好。