中等信任度的匿名类型,与反射一起使用,而不是与表达式一起使用
我在 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
。
另一个类似情况没有解决问题
I'm doing custom projections on Linq queries in Medium Trust and I get a MethodAccessException
or TypeAccessException
complaining about reflection and security rights.
I've simplified the code to the following:
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 }
In Full Trust, anon2
and anon3
will be created. In Medium Trust only anon2
will be created.
Another similar situation did not solve the issue
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这是因为编译器将匿名类型创建为
内部
。这意味着程序集外部的代码将无法访问这些类型。当您自己进行反射时,所有调用都来自您的程序集,因此这是允许的。但是,当您引入表达式时,调用开始来自框架 DLL,因此它们会停止。解决此类问题的一种简单方法是使用 InternalsVisibleTo 属性。只需添加以下内容即可:
您将能够创建 lambda。然而,当你去编译它时,你会得到类似的权限异常。在这种情况下,Compile 方法最终会触发 mscorlib.dll 中的一些代码来尝试访问您的类型。我尝试添加:
但这似乎不起作用。我认为这可能与 mscorlib 是强签名的事实有关。根据InternalsVisislbeTo的文档:
也许如果您的代码已签名,它就会起作用。或者也许您甚至不需要调用 Compile() - 也许这只是为了测试?添加对 System.Core 的引用值得一试。
This is caused because anonymous types are created as
internal
by the compiler. That means code outside of your assembly won't be able to access the types. When you do the reflection yourself, all the calls are coming from your assembly so it is allowed. But when you introduce expressions, the calls start coming from framework DLLs and so they get stopped.An easy way to solve problems of this nature is with the InternalsVisibleTo attribute. By just adding this:
you'll be able to create the lambda. However, when you go to compile it, you get a similar permission exception. In that case, the Compile method ends up triggering some code in mscorlib.dll to try to access your type. I tried adding:
but that didn't seem to work. I think it might have to do with the fact that mscorlib is strongly signed. According to the documentation of InternalsVisislbeTo:
Perhaps if your code was signed, it would work. Or perhaps you don't even need the call to Compile() - maybe that was just for testing? Adding the reference to System.Core is worth a try.
如果您想对其进行单元测试而不是在浏览器中继续进行测试,我最近刚刚发布了一篇关于如何在 Medium Trust 中对代码进行单元测试的帖子,
第三部分有一个可下载的程序集,其中包含您可以使用的基类任何 NUnit 测试装置,它包含其他部分的链接:http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with-nunitpart- Three-umbraco-framework-testing/
If you'd like to unit test this rather than keep testing in a browser, I've just put up a post just recently on how to unit test code in Medium Trust
Part three has a downloadable assembly with a base class you can use for any NUnit test fixture, and it contains links to the other parts: http://boxbinary.com/2011/10/how-to-run-a-unit-test-in-medium-trust-with-nunitpart-three-umbraco-framework-testing/