首页 > 代码库 > 逗我玩吗?ViewBag.XXX 找不到编译动态表达式所需的一种或多种类型
逗我玩吗?ViewBag.XXX 找不到编译动态表达式所需的一种或多种类型
现在接手的项目是用 .NET 4 + MVC4 做的.
我尝试着用 Unity 变更一下其中的一个功能的实现. 但是 Unity.MVC4 依赖于 Unity 3 以上的版本, Unity 3 又依赖于 .NET 4.5, Unity.MVC3 又只能用于 MVC3 的项目 . 按我的性格就是要把整个工程改为 .NET 4.5 的算球了, 但是有有同事说 .NET 4.5 是新东西,不知道稳定不稳定. 至于稳定不稳定, 我无从考证.
不用 .NET 4.5 , 那只好自己实现对 Controller / Filter 的注入了.
昨天在家搞到1点多,把注入这块实现了,做了个DEMO ,挺好的. 今天往项目里加的时候, 发现个问题:
ViewBag.xxx 找不到编译动态表达式所需的一种或多种类型。是否缺少引用
对比DEMO,没有发现有什么不同, 基本一至. 搜了一圈, 有说是 System.Core 和 Microsoft.CSharp 的, 有说是 GAC的.
我把 GAC 里的 System.Core 3.5 的版本删了, Microsoft.CSharp 也重新引用了, 也重启了, 问题依旧.
搞了一个下午, 我自己都不好意思.
实在不行, 那就只能排除了 :
首先, 不配置 Unity
嗯,不配置 Unity 是不会报那个XXX错误的.
接着,启用 Unity 的配置:
一旦启用Unity 的配置, 就会有上面的那个错误. 不用 configSource 也一样!
尝试对 config 做各种修改, 尝试删除 : C:\windows\Microsoft.NET\Framework\v4.0.30319\Temporary ASP.NET Files\root 下的文件夹 , 结果都一样, 一加上那段配置就有这个错, 一去掉啥事没有. 逗我玩的满头大汗...
这个错误,编译的时候是不会有的, 但是一打开 xxx.cshtml 就会出现.
数据库DOWN掉了一下午, 下班前才临时搭了一个用用, 所以,我一直没有运行调试, 临时数据库搞好后,我才调试了一把, 结果调试完后,这个神奇的错误消失了! 我都不道是哪一步影响的.
自己逗自己玩了一下午...
附上注入的实现, 是通过 IControllerActivator 实现的, 赶脚比用 ControllerFactory 实现的要简单些:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Web.Mvc; 7 using System.Web.Routing; 8 9 namespace Common.MVC { 10 public class UnityControllerActivator : IControllerActivator { 11 IController IControllerActivator.Create(System.Web.Routing.RequestContext requestContext, 12 Type controllerType) { 13 return DependencyResolver.Current.GetService(controllerType) as IController; 14 } 15 16 } 17 }
1 using Microsoft.Practices.Unity; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 using System.Web.Mvc; 8 9 namespace Common.MVC { 10 public class UnityDependencyResolver : IDependencyResolver { 11 12 private IUnityContainer Container; 13 14 public UnityDependencyResolver(IUnityContainer container) { 15 if (container == null) 16 throw new ArgumentNullException("container"); 17 18 this.Container = container; 19 } 20 21 public object GetService(Type serviceType) { 22 if (this.Container.IsRegistered(serviceType) 23 || typeof(IController).IsAssignableFrom(serviceType)) { 24 var obj = this.Container.Resolve(serviceType); 25 return obj; 26 } 27 return null; 28 } 29 30 public IEnumerable<object> GetServices(Type serviceType) { 31 return this.Container.ResolveAll(serviceType); 32 } 33 34 } 35 }
1 using Microsoft.Practices.Unity; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Web.Mvc; 7 8 namespace Common.MVC { 9 public class UnityFilterProvider : FilterAttributeFilterProvider { 10 11 private IUnityContainer Container; 12 13 public UnityFilterProvider(IUnityContainer container) { 14 if (container == null) 15 throw new ArgumentNullException("container"); 16 this.Container = container; 17 } 18 19 20 private IEnumerable<Filter> BuildUp(List<Filter> filters) { 21 filters.ForEach(f => { 22 this.Container.BuildUp(f.Instance.GetType(), f.Instance); 23 }); 24 25 return filters; 26 } 27 28 public override IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { 29 var filters = base.GetFilters(controllerContext, actionDescriptor).ToList(); 30 return this.BuildUp(filters); 31 } 32 33 //private IEnumerable<FilterAttribute> BuildUp(List<FilterAttribute> attrs) { 34 // attrs.ForEach(a => { 35 // this.Container.BuildUp(a.GetType(), a); 36 // }); 37 // return attrs; 38 //} 39 40 //下面这两个方法的结果还是要返回到 GetFilters 内 41 //protected override IEnumerable<FilterAttribute> GetActionAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { 42 // var attrs = base.GetActionAttributes(controllerContext, actionDescriptor).ToList(); 43 // return this.BuildUp(attrs); 44 //} 45 46 //protected override IEnumerable<FilterAttribute> GetControllerAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { 47 // var attrs = base.GetControllerAttributes(controllerContext, actionDescriptor).ToList(); 48 // return this.BuildUp(attrs); 49 //} 50 51 } 52 }
1 using Microsoft.Practices.Unity; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Web; 6 using System.Web.Mvc; 7 using Microsoft.Practices.Unity.Configuration; 8 using Common.MVC; 9 10 namespace UnityAndMvc4NET4Test { 11 public class UnityConfig { 12 13 public static void Config() { 14 var container = new UnityContainer(); 15 16 container.RegisterType<IControllerActivator, UnityControllerActivator>(); 17 FilterProviders.Providers.Add(new UnityFilterProvider(container)); 18 19 container.LoadConfiguration(); 20 21 DependencyResolver.SetResolver(new UnityDependencyResolver(container)); 22 } 23 24 } 25 }
1 public class MvcApplication : System.Web.HttpApplication { 2 protected void Application_Start() { 3 UnityConfig.Config(); 4 ... 5 ... 6 ...
目前还没有找到自动 GlobalFilters.Filters 实现自动注入的方法, 只能搞成自映射的方式.
filters.Add(DependencyResolver.Current.GetService<GlobalExceptionFilter>());
请大侠指点一二.