我正在使用Medium Trust对Linq查询进行自定义投影,我得到MethodAccessException
或TypeAccessException
抱怨反思和安全权利。
我已将代码简化为以下内容:
var anon1 = new { Name = "Bill Gates" };
var ctor = anon1.GetType().GetConstructors().First();
// With native Reflection it works
var anon2 = ctor.Invoke(new object[] { "Steve Ballmer" });
var expr = Expression.New(ctor, Expression.Constant("Scott Guthrie"));
var lamb = Expression.Lambda(expr); // This throws in Medium Trust
var anon3 = lamb.Compile().DynamicInvoke();
anon1.ToString(); // --> { Name = Bill Gates }
anon2.ToString(); // --> { Name = Steve Ballmer }
anon3.ToString(); // --> { Name = Scott Guthrie }
在完全信任中,将创建anon2
和anon3
。在中型信任中,只会创建anon2
。
另一个similar situation没有解决问题
答案 0 :(得分:4)
这是因为编译器将匿名类型创建为internal
。这意味着程序集外部的代码将无法访问类型。当你自己进行反射时,所有的调用都来自你的程序集,所以它是允许的。但是当你引入表达式时,调用开始来自框架DLL,因此它们会被停止。
解决此类问题的简单方法是使用InternalsVisibleTo属性。只需添加:
[assembly: InternalsVisibleTo("System.Core")]
你将能够创建lambda。但是,当您编译它时,您会收到类似的权限异常。在这种情况下,Compile方法最终会触发mscorlib.dll中的一些代码来尝试访问您的类型。我尝试添加:
[assembly: InternalsVisibleTo("mscorlib")]
但这似乎不起作用。我认为这可能与mscorlib强烈签名的事实有关。根据InternalsVisislbeTo的文件:
当前程序集和好友程序集都必须是未签名的,或者 两者都必须用强名称签名。
也许如果您的代码已经签名,它就可以了。或许你甚至不需要调用Compile() - 也许这仅仅是为了测试?添加对System.Core的引用值得一试。
答案 1 :(得分:0)
如果您想对此进行单元测试而不是在浏览器中进行测试,我最近刚刚发布了一篇关于如何在Medium Trust中测试代码的文章
第三部分有一个可下载的程序集,它有一个可用于任何NUnit测试夹具的基类,它包含指向其他部分的链接:http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with-nunitpart-three-umbraco-framework-testing/