2012-04-30 9 views
7

के गुणों को पुनर्प्राप्त करने के लिए कैसे करें मैं किसी भी प्रमाणीकरण विशेषताओं पर ध्यान देने की कोशिश कर रहा हूं जो एक एमवीसी 3 अनुप्रयोग में मेरे नियंत्रकों में सजाने की क्रिया विधियां हो सकती हैं। मैं इसे अपने स्वयं के एचटीएमएल हेल्पर एक्सटेंशन विधियों में कर रहा हूं जो मूल रूप से एक्शनलिंक के लिए रैपर हैं (आपको रनटाइम पर जो जानकारी उपलब्ध है उसका संदर्भ देने के लिए)। मेरे पास जगह पर एक बुनियादी समाधान है, लेकिन अधिभारित तरीकों ने इसे अभी विस्फोट कर दिया है। मुझे पता है कि ढांचा आंतरिक रूप से क्रिया विधियों के लिए यूआरएल को हल कर रहा है, लेकिन System.Web.Mvc.LinkExtensions के लिए कोड को देखने के बाद, मुझे अभी भी यह नहीं मिला है कि यह कैसे हो रहा है, इसलिए मैं थोड़ा सा अटक गया हूं इस मुद्दे से निपटने के लिए।अनुरोधित कार्य विधि

private static bool _IsUserAuthorized(HtmlHelper html, 
    string controllerName, string actionName) 
{ 
    controllerName = controllerName ?? 
    html.ViewContext.RouteData.GetRequiredString("controller"); 

    var factory = ControllerBuilder.Current.GetControllerFactory(); 
    var controller = factory.CreateController(
    html.ViewContext.RequestContext, controllerName); 

    Type controllerType = controller.GetType(); 
    var methodInfo = controllerType.GetMethod(actionName, 
    BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance); 

    ... check authentication 
} 

तो मेरे वर्तमान समस्या यह है कि जब एक विधि ओवरराइड की गई है, मैं मिलता है "अस्पष्ट मिलान पाया" अपवाद:

यहाँ कोड मैं अब तक प्रासंगिक विधि हल करने के लिए है। मुझे लगता है कि मुझे विधि के किसी भी पैरामीटर को हल करने के लिए रूटवेल को संसाधित करने की आवश्यकता है ताकि मैं स्पष्ट रूप से सही पहचान सकूं। क्या किसी के पास यह कैसे करना है इस पर कुछ पॉइंटर्स हैं? वैकल्पिक रूप से, क्या ढांचा पहले से आवश्यक सटीक विधि को हल करने का साधन प्रदान करता है?

बहुत बहुत धन्यवाद!

+0

ठीक कॉपी किया है, तो मैं MVC3 स्रोत कोड में खुदाई रखा है और इस तरह मैं एक ControllerDescriptor उदाहरण और उपयोग प्राप्त करने की आवश्यकता यह लग रहा है कि उपयुक्त कार्रवाई विधि के लिए एक ActionDescriptor प्राप्त करने के लिए। तो अगर ऐसा है, तो अनुरोध किया गया कार्रवाई विधि HtmlHelper.ViewContext.Controller में नियंत्रक नहीं है जब मैं उचित नियंत्रक के नियंत्रक कॉन्टेक्स्ट को कैसे प्राप्त करूं? –

+0

कंट्रोलर कॉन्टेक्स्ट प्राप्त करना बहुत सरल हो जाता है। एक नियंत्रक डिस्क्रिप्टर प्राप्त करना, इतना नहीं। कोई विचार? –

+0

नियंत्रक डिस्क्रिप्टर और एक्शन डिस्क्रिप्टर प्राप्त करने के लिए कोड मिला [यहां] (http://weblogs.asp.net/jeffreyzhao/archive/2009/01/30/extend-asp-net-mvc-for-asynchronous-action.aspx)। करीब आना ... –

उत्तर

2

संपादित करें: this page से अंतर्दृष्टि शामिल करने के लिए विधि को अपडेट किया गया। यह अंतिम संस्करण अनुरोधित कार्रवाई विधि के लिए प्राधिकरण फ़िल्टर को देखता है और यह जांचता है कि उपयोगकर्ता कार्रवाई करने के लिए अधिकृत है या नहीं।

इसलिए मैंने सिस्टम.Web.Mvc.ControllerActionInvoker में चारों ओर खोद दिया और मुझे आवश्यक विधियों और रचनाकारों को मिला। ControllerDescriptor.FindAction() कुंजी होने के समाप्त हो गया। नीचे, मैं विधि मैं ने लिखा है कि सभी विशेषताओं को पुनः प्राप्त करेगा

private static bool _IsUserAuthorized(HtmlHelper htmlHelper, 
    string controllerName, string actionName) 
{ 
    ControllerContext controllerContext = null; 
    //if controllerName is null or empty, we'll use the 
    // current controller in HtmlHelper.ViewContext. 
    if (string.IsNullOrEmpty(controllerName)) 
    { 
    controllerContext = htmlHelper.ViewContext.Controller.ControllerContext; 
    } 
    else //use the controller factory to get the requested controller 
    { 
    var factory = ControllerBuilder.Current.GetControllerFactory(); 
    ControllerBase controller = (ControllerBase)factory.CreateController(
     htmlHelper.ViewContext.RequestContext, controllerName); 
    controllerContext = new ControllerContext(
     htmlHelper.ViewContext.RequestContext, controller); 
    } 

    Type controllerType = controllerContext.Controller.GetType(); 
    ControllerDescriptor controllerDescriptor = new ReflectedControllerDescriptor(controllerType); 
    ActionDescriptor actionDescriptor = controllerDescriptor.FindAction(controllerContext, actionName); 
    if (actionDescriptor == null) 
    return false; 

    FilterInfo filters = new FilterInfo(FilterProviders.Providers.GetFilters(
    controllerContext, actionDescriptor)); 

    AuthorizationContext authContext = new AuthorizationContext(controllerContext, actionDescriptor); 
    foreach (IAuthorizationFilter authFilter in filters.AuthorizationFilters) 
    { 
    authFilter.OnAuthorization(authContext); 
    if (authContext.Result != null) 
     return false; 
    } 
    return true; 
} 
0

प्राधिकरण कोड जोड़ने का सामान्य तरीका Authorization Filter का उपयोग कर रहा है।

IAuthorizationFilter.OnAuthorizationAuthorizationContext ऑब्जेक्ट प्रदान करता है जिसमें ActionDescriptor संपत्ति है।

+0

हम पहले से ही प्राधिकरण फ़िल्टर का उपयोग कर रहे हैं, लेकिन जब तक कि मैं इसे याद नहीं कर रहा हूं, ढांचा आपको एक क्रिया का आह्वान करने से पहले प्राधिकरण का निरीक्षण करने का साधन प्रदान नहीं करता है। मैं उन उपयोगकर्ताओं से लिंक छिपाने की कोशिश कर रहा हूं जिनके पास लिंक किए जाने वाले कार्यों को करने के लिए उपयोग नहीं है, इसलिए मुझे HTML को प्रस्तुत करने से पहले प्राधिकरण विशेषताओं का निरीक्षण करने की आवश्यकता है। मुझे आवश्यक कार्यक्षमता के लिए श्रृंखला में ऑन-प्राधिकरण को संभालना बहुत देर हो जाएगा। –

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