Reputation: 191
We have recently started migrating to Castle Windsor and i'm having some issues getting our WCF service running. It is a regular windows service NOT HOSTED IN IIS where we serve up SSL material and use a custom X509CertificateValidator
to verify the client's presented certificate.
Below is the code i'm using to create the WCF service. It is in a separate project to the WCF service which references it.
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;
}
The service starts as expected (i can navigate to the service using chrome with no issues) and the service is presenting and validating the SSL material (i.e. hits the custom validator) but after that, the client gets this in a 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.
Below is a chunk of my App.Config
, i have tried to place the module in all areas that were suggested through googles and through some guesswork:
...
<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>
...
Im pretty much out of ideas. Does anyone know what could be the cause? If not, could anyone explain abit more about the error i'm getting? Any help would be much appreciated!
Upvotes: 4
Views: 2171
Reputation: 191
Once again i'm answering my own question (the next day after posting, oh dear) :P
This error message is being thrown here (thank god for open source!):
tldr - see below:
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());
}
...
}
From this I quickly gathered that the issue was that the PerWebRequestLifestyleModule
was not being initialized, which was ok for me as i did not need it for this service!
Looking further into my own code, some of my repositories that were being loaded for this service were set to use LifestylePerWebRequest
from when they were being used in our web console, bingo!
After adjusting them to something else (in this case 'LifestylePerWcfOperation`) all was working fine.
Upvotes: 6