5

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

Community
  • 1
  • 1
Yona
  • 9,392
  • 4
  • 33
  • 42
  • So I've been trying a bit to reproduce this. Are you on .NET4? Do you have any advice on how to repro? I assume anon1 is successfully created on all situations? Have you tried to not use DynamicInvoke and just invoke the delegate directly? – Just another metaprogrammer Aug 17 '11 at 22:17
  • I'm using .NET 4. To reproduce it you have to run this code under Medium Trust. – Yona Aug 18 '11 at 14:27
  • The code throws on the `Expression.Lambda()` call, not on `Compile()` – Yona Aug 18 '11 at 14:29

2 Answers2

4

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:

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

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:

[assembly: InternalsVisibleTo("mscorlib")]

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:

Both the current assembly and the friend assembly must be unsigned, or both must be signed with a strong name.

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.

Stephen McDaniel
  • 2,938
  • 2
  • 24
  • 53
  • How come native reflection does work? Since the reflection classes are defined in other assemblies, I would expect the same behavior. – Yona Aug 18 '11 at 14:26
  • The code throws on the `Expression.Lambda()` call, not on `Compile()` – Yona Aug 18 '11 at 14:28
  • The reflection classes are the one that do the permission check. So they do their check from the context of their caller. With direct reflection, you are the caller. With Expressions, the Linq.Expression classes are the caller. – Stephen McDaniel Aug 18 '11 at 15:59
  • It still throws on Expression.Lambda even with the InternalsVisislbeTo? I was able to execute the Lambda call in medium trust. Can you post the exeception details. Also, what kind of app is this? WinForm, Command Line, ASP.Net, etc.? – Stephen McDaniel Aug 18 '11 at 16:01
  • The code is part of a Microsoft Dynamics CRM Plugin. All Plugins run under Medium Trust and have to be signed. I tried adding the InternalsVisibleTo with the public key with no luck. – Yona Aug 18 '11 at 17:10
0

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/

Alex Norcliffe
  • 2,439
  • 2
  • 17
  • 21