IIS托管WCF应用中Ninject拦截遇ServiceActivationException问题
嘿,很高兴你已经搞定了服务验证异常!不过既然之前碰到了ServiceActivationException的问题,我来梳理下Ninject整合WCF拦截时最容易踩的坑,帮你彻底把拦截功能跑顺:
1. 务必保证所有Ninject相关包版本完全匹配
版本不兼容是触发ServiceActivationException的头号原因!你引入的Ninject、Ninject.Web.Common、Ninject.Extensions.Wcf、Ninject.Extensions.Interception、Ninject.Extensions.Interception.DynamicProxy以及Castle.Core,必须用完全一致的版本。比如Ninject用3.3.x的话,所有扩展包都要对应3.3.x,Castle.Core也要选适配的版本(比如Ninject 3.3.x对应Castle.Core 4.x系列)。
2. 正确配置拦截器与服务绑定
先定义你的拦截器类
比如一个简单的日志拦截器:
public class ServiceLoggingInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { // 前置拦截逻辑 Trace.WriteLine($"准备调用方法: {invocation.Method.Name}"); // 执行原方法 invocation.Proceed(); // 后置拦截逻辑 Trace.WriteLine($"方法调用完成: {invocation.Method.Name}"); } }
在Ninject内核中绑定服务并启用拦截
打开你的NinjectWebCommon.cs(或者自定义的Ninject模块),注册拦截器的同时,给WCF服务绑定加上拦截配置:
private static void RegisterServices(IKernel kernel) { // 注册拦截器实例 kernel.Bind<IInterceptor>().To<ServiceLoggingInterceptor>(); // 绑定WCF服务契约到实现类,并启用拦截 kernel.Bind<IMyWcfService>().To<MyWcfServiceImpl>() .Intercept().With<ServiceLoggingInterceptor>(); // 如果要拦截这个服务的所有方法,也可以用 .InterceptAll().With<ServiceLoggingInterceptor>() }
3. 确保.svc文件正确指定Ninject的ServiceHostFactory
这步很容易漏!你的.svc文件必须把Factory换成Ninject的实现,不能用默认的WCF宿主工厂。比如:
<%@ ServiceHost Language="C#" Debug="true" Service="YourNamespace.MyWcfServiceImpl" Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory" %>
注意Service属性要填服务实现类的完整命名空间,Factory的类名和命名空间不能写错,否则直接触发激活异常。
4. 检查WCF契约与配置的兼容性
拦截依赖Castle动态代理生成,所以要确保:
- 你的WCF服务契约(接口)是public的
- 如果是基于类的WCF服务(而非接口),要被拦截的方法必须是
virtual的(不过WCF通常推荐接口契约,这步可以忽略) - web.config里的WCF端点配置要正确,契约、绑定、地址不能有拼写错误
5. 深挖内部异常找根源
ServiceActivationException往往是个“壳”,里面包着真实的错误原因。你可以在web.config里开启详细错误输出:
<system.serviceModel> <serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" /> <behaviors> <serviceBehaviors> <behavior> <serviceDebug includeExceptionDetailInFaults="true"/> <serviceMetadata httpGetEnabled="true"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel>
之后直接在浏览器访问.svc文件,或者用WCF测试客户端调用,就能看到具体的错误信息——比如代理生成失败、绑定错误、依赖缺失等,针对性解决就快多了。
既然你已经解决了服务验证异常,大概率是上述某个环节没配置到位,比如版本不匹配、.svc的Factory没设对,或者拦截绑定的方式有误。再核对一遍这些步骤,应该就能让拦截功能正常跑起来了!
内容的提问来源于stack exchange,提问作者Brandon

