5

我正在对 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 }

完全信任,anon2并将anon3被创建。仅在中等信任anon2中创建。

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

4

2 回答 2

4

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

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

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

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

[assembly: InternalsVisibleTo("mscorlib")]

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

当前程序集和友元程序集都必须是未签名的,或者都必须使用强名称进行签名。

也许如果您的代码已签名,它将起作用。或者你甚至不需要调用 Compile() - 也许这只是为了测试?添加对 System.Core 的引用值得一试。

于 2011-08-18T08:16:36.080 回答
0

如果您想对此进行单元测试而不是继续在浏览器中进行测试,我最近刚刚发布了一篇关于如何在 Medium Trust 中对代码进行单元测试的帖子

第三部分有一个可下载的程序集,其中包含一个可用于任何 NUnit 测试夹具的基类,它包含指向其他部分的链接:http: //boxbinary.com/2011/10/how-to-run-a-unit-使用 nunitpart-three-umbraco-framework-testing/ 进行中等信任测试

于 2011-10-21T17:02:25.903 回答