Frage

Beim Versuch, einen Ausdruck in einem App Medium Vertrauen Web zu kompilieren Ich erhalte eine Method. Kennt jemand einen anderen Weg, um einen Ausdruck unter mittlerer Vertrauenswürdigkeit oder eine Abhilfe zu kompilieren, diese Ausnahme zu vermeiden?

Der Code, der die Ausnahme auslöst:

Expression<Func<object>> efn = 
  Expression.Lambda<Func<object>>(Expression.Convert((plan,typeof(object)));

Func<object> fn = efn.Compile(); // Exception thrown here

Die Variable Plan ist ein Ausdruck, der die folgenden Ausführungsplan darstellt:

{
  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 [] {}
  )
}

Der vollständige Stack-Trace:

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)
War es hilfreich?

Lösung

Das zugrunde liegende Problem ist, dass die Art zu System.Activator.CreateInstance(Type type, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes) weitergegeben wird entweder nicht öffentlich, oder einen Konstruktor hat, der nicht öffentlich ist.

- angesichts der Einfachheit des Codes Beispiels im Vergleich zu der Tiefe des Stacktrace ich das Problem liegt nicht in plan glauben, aber in einem Ausdruck innerhalb plan (da Sie in Ihrem Kommentar auf Marcs Antwort sagen, dass es auch ein Ausdruck) dass Referenzen der Typ, der dann beschränkt ist.

Der Ausdruck, der die Quelle des Fehlers ist hier ein ConstantExpression, die von dem geschützten Typ sein muss.

Die einzige verwirrende Sache über dieses ist jedoch, dass die Art Argument, dass AddGlobal zu Activator.CreateInstance geht StrongBox<T> ist, die Öffentlichkeit und hat einen öffentlichen Konstruktor -. Was bedeuten würde, dass dieser Fehler nicht möglich sein sollte,

Vielleicht aber es ist etwas versteckt mit StrongBox<T> verbunden, dass wir nicht durch Reflector sehen können.

Also, ich würde auf dem ganzen Ausdrucksbaum von plan dargestellt werden Suche und Prüfung aller in ConstantExpressions referenzierten Typen zu gewährleisten, dass sie alle zugänglich sind. Wenn nach tun, dass alle Arten zugänglich gezeigt werden, sind immer noch dieser Fehler auftritt, dann könnte es ein Bug im Rahmen sein.

Allerdings - ich hätte gedacht, dass ein solcher Fehler bereits als ConstantExpression für etwas so einfach gefunden habe würde

EDIT (Ersetzen Zurück Edit) mit der Antwort

Ich habe es, und es ist ein sehr kleines Problem. Sie können mit diesem kleinen Stück Code in einer aspx Seite reproduzieren, die in mittlerer Vertrauenswürdigkeit ausgeführt wird, ist:

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

Also, in dem Code, den Sie zur Verfügung gestellt haben, dann ist es der Ausdruck das zweite Argument zu ChangeType darstellt (ich brauchte eine Weile zu erkennen, dass das ist ein Sub Sonic-Verfahren), das eine Type zu sein scheint (kann das nicht sehen Code, aber ich denke, es ist eine vernünftige Vermutung!).

Es ist im Ausdruck als ConstantExpression einer Type Instanz gebacken. Fragen Sie nicht, wie ich auf der Parameter verengt - viele Stapel kriechenden und Reflektor Arbeit;)

Wie in der ersten Hälfte meiner Antwort erwähnt, ist es schwierig zu sehen, wie der Code, dass die Expression Baum-Compiler verwendet jemals eine Method erstellen, da es sich immer die Öffentlichkeit Ctor des StrongBox<T> Typ Zugriff.

Allerdings wäre es aufregen, wenn der Typ in geben als die generische nicht öffentlich ist. "Aber warten Sie," Sie sagen: "Type Öffentlichkeit ist".

Das könnte sein, aber die Type Instanz zur Laufzeit aus typeof() oder GetType() zurückgegeben wird, ist nicht - es ist eine Instanz von RuntimeType - das ist interne

.

Welche ist auch, warum der obige Codeausschnitt wird auch die gleichen Fehler auslösen.

Das Update

Ändern Sie den Code, der die Type Argument für ChangeType(,) von

produziert
Expression.Constant([type])

(was ich werde fast garantieren, dass es im Moment) zu

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

Das funktioniert, weil Sie explizit die Compiler zu sagen, die Öffentlichkeit Type für die Konstante zu verwenden, anstelle der reflektierten Art von RuntimeType.

Sie können dieses Update testen, indem Sie es zu meinem Beispielcode in dem vorherigen Block und die Anwendung erneut ausgeführt wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top