首页 > 代码库 > 逗我玩吗?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 }
UnityControllerActivator

 

 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 }
UnityDependencyResolver

 

 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 }
UnityFilterProvider

 

 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 }
UnityAndMvc4NET4Test

 

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>());

 

请大侠指点一二.