Выражение .compile в среде средней трастовой среды

StackOverflow https://stackoverflow.com/questions/3194678

  •  02-10-2019
  •  | 
  •  

Вопрос

При попытке скомпилировать выражение в веб -приложении Medium Trust, я получаю методикуксекции. Кто -нибудь знает другой способ составить выражение под средним доверием или обходной путь, чтобы избежать этого исключения?

Код, который бросает исключение:

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 и изучить все типы, упомянутые в ConstantExpressionS, чтобы убедиться, что они все доступны. Если после этого все типы показаны доступными, эта ошибка все еще возникает, то это может быть ошибка в структуре.

Однако я бы подумал, что такая ошибка была бы найдена уже за что -то столь простое, как ConstantExpression!

Редактировать (заменить предыдущее редактирование) С ответом

У меня это есть, и это очень тонкая проблема. Вы можете воспроизвести с этим небольшим количеством кода на странице ASPX, которая настроена на запуск в Medium Trust:

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());

Итак, в предоставленном вами коде это выражение, представляющее второй аргумент ChangeType (мне потребовалось некоторое время, чтобы понять, что это метод субсолины), который, по -видимому, Type (Не вижу кода, но я думаю, что это разумное предположение!).

Он запечен в выражении как ConstantExpression а Type пример. Не спрашивайте, как я сузил параметр - много ползания стека и отражателя работы;)

Как упоминалось в первой половине моего ответа, трудно понять, как код, который использует компилятор дерева выражения, может создать методикуксекции, поскольку он всегда доступ к публичному CTOR StrongBox<T> тип.

Тем не менее, было бы расстроено, если бы тип прошел, поскольку общий не является публичным. "Но подожди", говоришь ты, "Type публично! ».

Это может быть, но Type экземпляр возвращается во время выполнения из typeof() или же GetType() нет - это экземпляр RuntimeType - который внутренний.

Вот почему приведенный выше фрагмент кода также вызовет ту же ошибку.

Исправление

Изменить код, который создает Type аргумент для ChangeType(,) из

Expression.Constant([type])

(Что я почти гарантирую, что это сейчас)

Expression.Constant([type], typeof(Type))

Это работает, потому что вы явно говорите компилятору использовать общественность Type для постоянной, вместо отраженного типа RuntimeType.

Вы можете проверить это исправление, применив его к моему примеру кода в предыдущем блоке и повторно выполнять.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top