表現。中程度の信頼環境における
-
02-10-2019 - |
質問
Medium Trust Webアプリで式をコンパイルしようとするとき、MethodAccesSexceptionを取得しています。この例外を回避するために、中程度の信頼または回避策の下で表現をコンパイルする別の方法を知っている人はいますか?
例外をスローするコード:
Expression<Func<object>> efn =
Expression.Lambda<Func<object>>(Expression.Convert((plan,typeof(object)));
Func<object> fn = efn.Compile(); // Exception thrown here
変数計画は、次の実行計画を表す表現です。
{
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 [] {}
)
}
フルスタックトレース:
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)
解決
ここでの根本的な問題は、に渡されているタイプが System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes)
公開されていないか、公開されていないコンストラクターがあります。
さて - コードの例とスタックトレースの深さの単純さを考えると、問題はないと思います plan
, 、しかし、内の表現で plan
(それも表現であるというマークの答えについてコメントしていると言っているので)。
ここのエラーの原因である式は ConstantExpression
これは制限されたタイプでなければなりません。
しかし、これについて唯一の混乱を招くことは、タイプの引数が AddGlobal
にパス Activator.CreateInstance
は StrongBox<T>
, 、公開されており、パブリックコンストラクターがあります。これは、このエラーが不可能であることを意味します。
おそらく、しかし、に関連する隠されたものがあります StrongBox<T>
リフレクターを通して見ることができないこと。
だから、私はによって表される表現ツリー全体を見ているでしょう plan
参照されるすべてのタイプを調べます ConstantExpression
sすべてがアクセス可能であることを確認します。それを行った後、すべてのタイプがアクセス可能であることが示された場合、このエラーはまだ発生します。フレームワークのバグになる可能性があります。
しかし、私はそのようなバグがすでに、 ConstantExpression
!
編集(以前の編集の置換) 答えで
私はそれを持っています、そしてそれは非常に微妙な問題です。 Medium Trustで実行するように構成されている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());
したがって、あなたが提供したコードでは、それは次の2番目の引数を表す式です ChangeType
(それがサブソニックの方法であることに気付くのにしばらく時間がかかりました)、それは Type
(コードは見えませんが、合理的な推測だと思います!)。
それは式として式で焼かれています ConstantExpression
の Type
実例。パラメーターをどのように絞り込んだか尋ねないでください - たくさんのスタッククロールとリフレクターの仕事;)
私の回答の前半で述べたように、Expression Treeコンパイラが使用するコードがMethodAccesSexceptionを作成する方法を確認することは困難です。 StrongBox<T>
タイプ。
ただし、ジェネリックが公開されていないため、タイプが渡された場合、それは動揺します。 「でも待って」とあなたは言う」Type
パブリックです!」
それはそうかもしれませんが、 Type
インスタンスは実行時に返されます typeof()
また GetType()
そうではありません - それはのインスタンスです RuntimeType
- それは 内部.
また、上記のコードスニペットが同じエラーをトリガーする理由でもあります。
修正
生成されるコードを変更します Type
の議論 ChangeType(,)
から
Expression.Constant([type])
(私はそれが現時点であることをほぼ保証します)
Expression.Constant([type], typeof(Type))
これは、コンパイラに一般の人々を使用するように明示的に言っているためです Type
一定の場合、反射されるタイプの代わりに RuntimeType
.
この修正は、前のブロックの私の例コードに適用して再ランニングすることでテストできます。