Ada*_*per 9 .net c# asp.net medium-trust
当尝试在中型信任Web应用程序中编译Expression时,我得到一个MethodAccessException.有没有人知道在中等信任下编译表达式的另一种方法或解决方法以避免此异常?
抛出异常的代码:
Expression<Func<object>> efn =
Expression.Lambda<Func<object>>(Expression.Convert((plan,typeof(object)));
Func<object> fn = efn.Compile(); // Exception thrown here
Run Code Online (Sandbox Code Playgroud)
变量计划是表示以下执行计划的表达式:
{
Convert(Query(MyProjectNamespace.MyDatabaseTableObject).Provider).Execute
(
new QueryCommand(
"SELECT [t0].[LinkId], [t0].[Url] FROM [dbo].[MyDatabaseTable] AS t0",
value(System.String[]),
r0 => new MyDatabaseTableObject()
{
Id = IIF(r0.IsDBNull(0), 0,
Convert(ChangeType(r0.GetValue(0), System.Int32))),
Url = IIF(r0.IsDBNull(1), null,
Convert(ChangeType(r0.GetValue(1), System.String)))
},
value(System.Collections.Generic.List[System.String])),
new [] {}
)
}
Run Code Online (Sandbox Code Playgroud)
完整堆栈跟踪:
at System.Reflection.MethodBase.PerformSecurityCheck(Object obj, RuntimeMethodHandle method, IntPtr parent, UInt32 invocationFlags)
at System.Reflection.RuntimeConstructorInfo.Invoke(BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
at System.Linq.Expressions.ExpressionCompiler.AddGlobal(Type type, Object value)
at System.Linq.Expressions.ExpressionCompiler.GenerateConstant(ILGenerator gen, Type type, Object value, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.GenerateConstant(ILGenerator gen, ConstantExpression c, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.Generate(ILGenerator gen, Expression node, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.GenerateArgs(ILGenerator gen, ParameterInfo[] pis, ReadOnlyCollection`1 args)
at System.Linq.Expressions.ExpressionCompiler.GenerateMethodCall(ILGenerator gen, MethodInfo mi, ReadOnlyCollection`1 args, Type objectType)
at System.Linq.Expressions.ExpressionCompiler.GenerateMethodCall(ILGenerator gen, MethodCallExpression mc, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.Generate(ILGenerator gen, Expression node, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.GenerateConvert(ILGenerator gen, UnaryExpression u)
at System.Linq.Expressions.ExpressionCompiler.Generate(ILGenerator gen, Expression node, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.GenerateConditional(ILGenerator gen, ConditionalExpression b)
at System.Linq.Expressions.ExpressionCompiler.Generate(ILGenerator gen, Expression node, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.GenerateMemberAssignment(ILGenerator gen, MemberAssignment binding, Type objectType)
at System.Linq.Expressions.ExpressionCompiler.GenerateBinding(ILGenerator gen, MemberBinding binding, Type objectType)
at System.Linq.Expressions.ExpressionCompiler.GenerateMemberInit(ILGenerator gen, ReadOnlyCollection`1 bindings, Boolean keepOnStack, Type objectType)
at System.Linq.Expressions.ExpressionCompiler.GenerateMemberInit(ILGenerator gen, MemberInitExpression init)
at System.Linq.Expressions.ExpressionCompiler.Generate(ILGenerator gen, Expression node, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.GenerateLambda(LambdaExpression lambda)
at System.Linq.Expressions.ExpressionCompiler.GenerateCreateDelegate(ILGenerator gen, LambdaExpression lambda)
at System.Linq.Expressions.ExpressionCompiler.Generate(ILGenerator gen, Expression node, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.GenerateArgs(ILGenerator gen, ParameterInfo[] pis, ReadOnlyCollection`1 args)
at System.Linq.Expressions.ExpressionCompiler.GenerateNew(ILGenerator gen, NewExpression nex, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.Generate(ILGenerator gen, Expression node, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.GenerateArgs(ILGenerator gen, ParameterInfo[] pis, ReadOnlyCollection`1 args)
at System.Linq.Expressions.ExpressionCompiler.GenerateMethodCall(ILGenerator gen, MethodInfo mi, ReadOnlyCollection`1 args, Type objectType)
at System.Linq.Expressions.ExpressionCompiler.GenerateMethodCall(ILGenerator gen, MethodCallExpression mc, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.Generate(ILGenerator gen, Expression node, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.GenerateConvert(ILGenerator gen, UnaryExpression u)
at System.Linq.Expressions.ExpressionCompiler.Generate(ILGenerator gen, Expression node, StackType ask)
at System.Linq.Expressions.ExpressionCompiler.GenerateLambda(LambdaExpression lambda)
at System.Linq.Expressions.ExpressionCompiler.CompileDynamicLambda(LambdaExpression lambda)
at System.Linq.Expressions.Expression`1.Compile()
at SubSonic.Linq.Structure.DbQueryProvider.Execute(Expression expression)
at SubSonic.Linq.Structure.QueryProvider.System.Linq.IQueryProvider.Execute(Expression expression)
at SubSonic.Linq.Structure.Query`1.GetEnumerator()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
at WebApplication1._Default.Page_Load(Object sender, EventArgs e)
at System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e)
at System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
Run Code Online (Sandbox Code Playgroud)
And*_*tan 15
这里的根本问题是传递给的类型System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
要么不公开,要么具有非公共构造函数.
现在 - 考虑到代码示例的简单性与堆栈跟踪的深度,我认为问题不在于plan
,而是在一个表达式中plan
(因为你在评论Marc的答案中说它也是一个表达式)引用了然后受到限制.
这里作为错误来源的表达式ConstantExpression
必须是受限制的类型.
关于这个唯一令人困惑的事情,但是,该类型的论点,即AddGlobal
传递给Activator.CreateInstance
就是StrongBox<T>
,这是公开的,具有公共构造-这将意味着,这个错误应该是不可能的.
然而,也许隐藏着与StrongBox<T>
我们无法通过Reflector看到的东西.
因此,我将查看由s 表示的整个表达式树,plan
并检查ConstantExpression
s中引用的所有类型,以确保它们都可访问.如果在执行此操作后显示所有类型都可访问,则仍会出现此错误,然后它可能是框架中的错误.
但是 - 我本以为这样的bug已经被发现已经找到了一个简单的东西ConstantExpression
!
用答案编辑(替换以前的编辑)
我知道了,这是一个非常微妙的问题.您可以在配置为以中等信任方式运行的aspx页面中使用此一点代码重现:
Type t = typeof([any type you fancy]);
Expression expr = Expression.Constant(t);
var lambda = Expression.Lambda<Func<Type>>(expr);
var del = lambda.Compile();
Response.Write(del().ToString());
Run Code Online (Sandbox Code Playgroud)
所以,在你提供的代码中,它是表示第二个参数的表达式ChangeType
(花了一些时间才意识到这是一个Sub Sonic方法),它似乎是一个Type
(看不到代码,但我认为它是一个合理的猜测!).
它在表达式中被烘焙ConstantExpression
为一个Type
实例.不要问我如何缩小参数 - 大量的堆栈爬行和反射器工作;)
正如我在答案的前半部分所提到的,很难看出Expression Tree编译器使用的代码如何创建一个MethodAccessException,因为它总是访问该StrongBox<T>
类型的公共ctor .
但是,如果作为泛型传入的类型不公开,则会感到不安."但等等,"你说," Type
是公开的!".
那可能是,但Type
实例在运行时返回typeof()
或GetType()
不是 - 它是一个实例RuntimeType
- 它是内部的.
这也是为什么上面的代码片段也会触发相同的错误.
修复
更改Type
为ChangeType(,)
from 生成参数的代码
Expression.Constant([type])
Run Code Online (Sandbox Code Playgroud)
(我几乎可以保证它现在正好)
Expression.Constant([type], typeof(Type))
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为您明确告诉编译器使用public Type
来表示常量,而不是反射类型RuntimeType
.
您可以通过将其应用于上一个块中的示例代码并重新运行来测试此修复.
归档时间: |
|
查看次数: |
1107 次 |
最近记录: |