2010-07-07 9 views
9

एक मध्यम ट्रस्ट वेब ऐप में अभिव्यक्ति संकलित करने का प्रयास करते समय मुझे एक विधिAccessException मिल रहा है। क्या कोई इस अपवाद से बचने के लिए मध्यम ट्रस्ट या वर्कअराउंड के तहत एक अभिव्यक्ति संकलित करने के किसी अन्य तरीके से जानता है?अभिव्यक्ति <TDelegate> मध्यम ट्रस्ट पर्यावरण में कॉम्पाइल

कोड है कि अपवाद फेंकता है:

{ 
    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) 
+1

आपके पास गैर-सार्वजनिक सदस्यों तक पहुंचने के लिए 'प्रतिबिंबप्रमिशन (ReflectionPermissionFlag.MemberAccess) 'नहीं है। –

+0

@ जारोस्लाव - मुझे पता है कि त्रुटि का कारण है कि मैं यह काम करने की कोशिश कर रहा हूं कि उस अनुमति की आवश्यकता है और यदि यह संभव हो, तो इसे कैसे प्राप्त किया जाए। –

+1

@Adam: यदि आप किसी भी गैर-सार्वजनिक सदस्यों (गुणों, फ़ील्ड, विधियों, रचनाकारों) का उपयोग करते हैं, तो उनके बिना इसे आजमाएं (यदि आप कर सकते हैं)। यहां तक ​​कि बाहरी पैरामीटर भी ऐसे व्यवहार का कारण बन सकते हैं। उपयोग किए गए वर्गों के आस-पास "प्रतिबिंबित करने" का प्रयास करें ... –

उत्तर

15

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

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

चर योजना एक अभिव्यक्ति है जो निम्न कार्य योजना लागू करके का प्रतिनिधित्व करता है अंतर्निहित समस्या यह है कि इस प्रकार कोपर पास किया जा रहा है 0 या तो सार्वजनिक नहीं है, या एक निर्माता है जो सार्वजनिक नहीं है।

अब

- स्टैकट्रेस मेरा मानना ​​है कि समस्या plan में नहीं है की गहराई की तुलना में अपने कोड उदाहरण की सादगी को देखते हुए, लेकिन plan भीतर (एक अभिव्यक्ति में जब से तुम मार्क के जवाब पर अपनी टिप्पणी में कहते हैं कि यह भी एक अभिव्यक्ति है कि) जो उस प्रकार को संदर्भित करता है जिसे तब प्रतिबंधित किया जाता है।

अभिव्यक्ति जो यहां त्रुटि का स्रोत है ConstantExpression है जो प्रतिबंधित प्रकार का होना चाहिए।

इस बारे में केवल दुविधापूर्ण, तथापि, कि प्रकार तर्क यह है कि AddGlobalActivator.CreateInstance गुजरता StrongBox<T> है, जो सार्वजनिक है और एक सार्वजनिक निर्माता है - जो अर्थ होगा कि इस त्रुटि असंभव होना चाहिए।

शायद, StrongBox<T> से जुड़े कुछ छिपे हुए हैं जिन्हें हम परावर्तक के माध्यम से नहीं देख सकते हैं।

तो, मैं plan द्वारा प्रतिनिधित्व किए गए पूरे अभिव्यक्ति पेड़ को देख रहा हूं और ConstantExpression में संदर्भित सभी प्रकार की जांच कर रहा हूं ताकि यह सुनिश्चित किया जा सके कि वे सभी पहुंच योग्य हैं। यदि ऐसा करने के बाद सभी प्रकारों को सुलभ किया जा सकता है, तो यह त्रुटि अभी भी होती है तो यह ढांचे में एक बग हो सकती है।

हालांकि - मैंने सोचा होगा कि इस तरह की एक बग 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()); 

तो, कोड आपके द्वारा दिए गए, यह अभिव्यक्ति ChangeType को दूसरा तर्क का प्रतिनिधित्व है (ले लिया मुझे यह समझने में थोड़ी देर लग रही है कि यह एक उप सोनिक विधि है), जो Type प्रतीत होता है (कोड नहीं देख सकता लेकिन मुझे लगता है कि यह एक उचित अनुमान है!)।

यह Type उदाहरण के ConstantExpression के रूप में अभिव्यक्ति में बेक्ड है।मत पूछें कि मैंने पैरामीटर को कैसे संकुचित किया - बहुत सारे स्टैक क्रॉलिंग और परावर्तक काम;)

जैसा कि मेरे उत्तर के पहले भाग में बताया गया है, यह देखना मुश्किल है कि अभिव्यक्ति ट्री कंपाइलर का उपयोग कभी भी कैसे बना सकता है एक MethodAccessException, क्योंकि यह हमेशा StrongBox<T> प्रकार के सार्वजनिक ctor तक पहुंच रहा है।

हालांकि, जेनेरिक के रूप में पारित प्रकार सार्वजनिक नहीं होने पर यह परेशान हो जाएगा। "लेकिन रुको," आप कहते हैं, "Type सार्वजनिक है!"।

हो सकता है यही कारण है, लेकिन Type उदाहरण typeof() या GetType() से कार्यावधि में लौटे नहीं है - जो आंतरिक है - यह RuntimeType का एक उदाहरण है।

यही कारण है कि उपरोक्त कोड स्निपेट भी एक ही त्रुटि को ट्रिगर करेगा।

ठीक

बदलें कोड कि Type

Expression.Constant([type], typeof(Type)) 
करने से

Expression.Constant([type]) 

ChangeType(,) के लिए तर्क (जो मैं लगभग गारंटी देंगे कि इस समय वह है) पैदा करता है

यह काम करता है, क्योंकि आप सार्वजनिक रूप सेका उपयोग करने के लिए संकलक को स्पष्ट रूप से बता रहे हैं RuntimeType परिलक्षित प्रकार के बजाय, निरंतर के लिए।

आप इस फिक्स का परीक्षण पिछले ब्लॉक में अपने उदाहरण कोड में और इसे फिर से चलाने के द्वारा कर सकते हैं।

+0

धन्यवाद यह वास्तव में सहायक है, क्या आपके पास गैर सुलभ प्रकारों को ट्रैक करने के त्वरित तरीके से कोई सुझाव है? मुझे पूरा भरोसा है कि यह एक ढांचागत बग नहीं है, लेकिन मुझे सटीक कारण को एक महत्वपूर्ण चुनौती को इंगित करना है। –

+0

हम्म ... अच्छी तरह से मैंने सोचा कि आप यह कैसे कर सकते हैं। शायद आप एक अभिव्यक्ति विज़िटर का उपयोग कर सकते हैं जो 'कॉन्स्टेंटएक्सप्रेस' की तलाश में है जिसका प्रकार या तो सार्वजनिक नहीं है या जिसमें कम से कम एक गैर-सार्वजनिक कन्स्ट्रक्टर है-जो इसे कम करना चाहिए। एमएसडीएन के पास एक उदाहरण अभिव्यक्ति आगंतुक का लिंक है। मैं एक नज़र डालूंगा और इसे उत्तर पर पोस्ट करूंगा। –

+0

@Adam - मैंने कुछ जवाब के साथ अपना जवाब अपडेट किया है जो एमएसडीएन से उस लिंक के साथ निदान करने में आपकी सहायता कर सकता है, जिसे आपको अभिव्यक्ति वृक्ष आगंतुक के लिए आवश्यकता होगी। यह सही नहीं है - लेकिन यह आपको अपने रास्ते पर अच्छी तरह से स्थापित करना चाहिए मुझे उम्मीद है :) –

संबंधित मुद्दे