中等信任的匿名类型与反射一起工作,而不是与表达式一起工作

本文关键字:工作 一起 表达式 信任 类型 反射 | 更新日期: 2023-09-27 18:05:58

我在Medium Trust中对Linq查询做自定义投影,我得到一个MethodAccessExceptionTypeAccessException抱怨反射和安全权。

我将代码简化为如下:

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 }

在Full Trust模式下,将创建anon2anon3。在中等信任中,只会创建anon2

另一个类似的情况没有解决问题

中等信任的匿名类型与反射一起工作,而不是与表达式一起工作

这是因为编译器将匿名类型创建为internal。这意味着程序集之外的代码将无法访问这些类型。当您自己执行反射时,所有调用都来自您的程序集,因此这是允许的。但是当您引入表达式时,调用开始来自框架dll,因此它们被停止。

解决这类问题的一个简单方法是使用InternalsVisibleTo属性。只需添加以下内容:

[assembly: InternalsVisibleTo("System.Core")]

,您将能够创建lambda。但是,当您编译它时,会得到类似的权限异常。在这种情况下,Compile方法最终会触发mscorlib.dll中的一些代码来尝试访问您的类型。我试着添加:

[assembly: InternalsVisibleTo("mscorlib")]

但这似乎不起作用。我认为这可能与mscorlib是强符号有关。根据InternalsVisislbeTo的文档:

当前程序集和友元程序集都必须是无符号的,否则

如果你的代码被签名了,它可能会工作。或者您甚至不需要调用Compile()—也许这只是为了测试?添加对系统的引用。Core值得一试

如果你想进行单元测试,而不是在浏览器中进行测试,我最近刚刚发布了一篇关于如何在Medium Trust中进行单元测试的文章

第三部分有一个可下载的程序集,其中有一个基类,可以用于任何NUnit测试夹具,它包含到其他部分的链接:http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with-nunitpart-three-umbraco-framework-testing/