नियंत्रक के भीतर से नियंत्रक और कार्रवाई का नाम प्राप्त करें?


173

हमारे वेब एप्लिकेशन के लिए मुझे दृश्य के आधार पर प्राप्त और प्रदर्शित वस्तुओं के क्रम को बचाने की आवश्यकता है - या सटीक होना - नियंत्रक और कार्रवाई जिसने दृश्य उत्पन्न किया (और उपयोगकर्ता आईडी बेशक, लेकिन यह यहां बात नहीं है)।

प्रत्येक कंट्रोलर एक्शन में स्वयं को एक पहचानकर्ता देने के बजाय (डीबी आउटपुट के कुछ दृश्य-निर्भर छँटाई के लिए इसका उपयोग करने के लिए), मैंने सोचा कि नियंत्रक और एक्शन विधि से स्वचालित रूप से इस पहचानकर्ता को बनाना अधिक सुरक्षित और आसान होगा। से पुकारा गया।

मैं कंट्रोलर में एक्शन विधि से कंट्रोलर और एक्शन का नाम कैसे ले सकता हूँ? या क्या मुझे उसके लिए प्रतिबिंब की आवश्यकता है? मुझे लगता है कि यह बहुत आसान है, अग्रिम धन्यवाद!


1
प्रतिबिंब आपको विधि का नाम देगा जो कार्रवाई को संभालती है, लेकिन संभवत: आप आंद्रेई कोड द्वारा लौटाए गए कार्रवाई नाम को पसंद करते हैं।
शहरकीद

मुझे मूल रूप से हर कार्य के लिए एक असंदिग्ध पहचानकर्ता की आवश्यकता है जो एक दृष्टिकोण प्रदान करता है, इसलिए दोनों तरीके काम करेंगे। लेकिन आप सही हैं, आंद्रेई का जवाब निश्चित रूप से अधिक सुरुचिपूर्ण है।
एलेक्स

@citykid क्या ऐसे मामले हैं जहां ये मामले के अलावा शिष्टाचार में भिन्न हैं और "नियंत्रक" वर्ग के नामों के लिए प्रत्यय हैं?
जॉन

@ जॉन, ActionNameAttribute एसी # विधि को किसी भी कार्रवाई के नाम की अनुमति देता है: msdn.microsoft.com/en-us/library/…
citykid

@citykid ओह, ठीक है। यह एक तरह की अप्रचलित विशेषता है जिसे आप Routeमेरे द्वारा एकत्र की जाने वाली कार्य विधि की विशेषता के साथ मार्गों को निर्दिष्ट कर सकते हैं ? इसके अलावा, क्या नियंत्रकों का नाम बदलना भी संभव है?
जॉन

जवाबों:


345
string actionName = this.ControllerContext.RouteData.Values["action"].ToString();
string controllerName = this.ControllerContext.RouteData.Values["controller"].ToString();

13
कुछ मामलों में जहां आप व्यू फ़ाइल में नियंत्रक का नाम रखना चाहते हैं, तो आप बस इसका उपयोग कर सकते हैं। ViewContext.RouteData.Values ​​["नियंत्रक"]। ToString ();
अमोघ नाटु

यदि आप ऐसा करने जा रहे हैं (कार्रवाई और नियंत्रक नाम प्रदान करें), तो उन्हें सीधे असाइन क्यों न करें ???
मेटलफेनिक्स

1
@MetalPhoenix, क्या आप थोड़ा स्पष्ट कर सकते हैं कि आप किस मामले का उपयोग कर रहे हैं? ओपी को नियंत्रक या कार्रवाई को निर्दिष्ट करने की आवश्यकता नहीं है - उन्हें बस समझने की आवश्यकता है, सामान्य तरीके से, वर्तमान में संसाधित किए जाने वाले नियंत्रक और कार्रवाई क्या हैं।
आंद्रेई

1
दूसरी बार पढ़ने पर, क्या यह संभव है कि मैंने यहां कोड स्निपिट को गलत समझा? ... मान ["एक्शन"] जहाँ "एक्शन" एक कुंजी है न कि एक्शन को नाम दिया जाना चाहिए (जैसे "पासपास '' कोट्स के बिना" टाइप)? यह कहना है: अभी भी मान ["कार्रवाई"] के बजाय मान ["कार्रवाई"] होगा?
मेटलफेनिक्स

@MetalPhoenix, वास्तव में, "एक्शन" शाब्दिक एक महत्वपूर्ण है, और मान ["एक्शन"] "CurrentActionName" का उत्पादन करेगा
आंद्रेई

62

उस जानकारी को प्राप्त करने के लिए कुछ विस्तार विधियाँ हैं (इसमें आईडी भी शामिल है):

public static class HtmlRequestHelper
{
    public static string Id(this HtmlHelper htmlHelper)
    {
        var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;

        if (routeValues.ContainsKey("id"))
            return (string)routeValues["id"];
        else if (HttpContext.Current.Request.QueryString.AllKeys.Contains("id"))
            return HttpContext.Current.Request.QueryString["id"];

        return string.Empty;
    }

    public static string Controller(this HtmlHelper htmlHelper)
    {
        var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;

        if (routeValues.ContainsKey("controller"))
            return (string)routeValues["controller"];

        return string.Empty;
    }

    public static string Action(this HtmlHelper htmlHelper)
    {
        var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;

        if (routeValues.ContainsKey("action"))
            return (string)routeValues["action"];

        return string.Empty;
    }
}

उपयोग:

@Html.Controller();
@Html.Action();
@Html.Id();

1
सर्वश्रेष्ठ और पूर्ण समाधान, धन्यवाद झोन
उमर अब्बास

24

उपयोगी हो सकता है। मुझे नियंत्रक के निर्माण में कार्रवाई की आवश्यकता थी , और यह एमवीसी जीवनचक्र के इस बिंदु पर प्रकट होता thisहै, आरंभीकृत नहीं है, और ControllerContext = null। एमवीसी जीवन चक्र में देरी करने और ओवरराइड करने के लिए उपयुक्त फ़ंक्शन नाम खोजने के बजाय, मैंने अभी कार्रवाई को पाया RequestContext.RouteData

लेकिन ऐसा करने के लिए, जैसा HttpContextकि कंस्ट्रक्टर में किसी भी संबंधित उपयोग के साथ है , आपको पूर्ण नाम स्थान निर्दिष्ट करना होगा, क्योंकि इसे this.HttpContextभी आरंभिक नहीं किया गया है। सौभाग्य से, ऐसा प्रतीत होता है System.Web.HttpContext.Currentकि यह स्थिर है।

// controller constructor
public MyController() {
    // grab action from RequestContext
    string action = System.Web.HttpContext.Current.Request.RequestContext.RouteData.GetRequiredString("action");

    // grab session (another example of using System.Web.HttpContext static reference)
    string sessionTest = System.Web.HttpContext.Current.Session["test"] as string
}

नोट: संभवतः HttpContext में सभी संपत्तियों तक पहुंचने का सबसे समर्थित तरीका नहीं है, लेकिन RequestContext और सत्र के लिए यह मेरे आवेदन में ठीक काम करता है।


11
var routeValues = HttpContext.Current.Request.RequestContext.RouteData.Values;
if (routeValues != null) 
{
    if (routeValues.ContainsKey("action"))
    {
        var actionName = routeValues["action"].ToString();
                }
    if (routeValues.ContainsKey("controller"))
    {
        var controllerName = routeValues["controller"].ToString();
    }
}


4

अभी तक मेरे पास इतना ही है:

var actionName = filterContext.ActionDescriptor.ActionName;
var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;

3

यहाँ एक नाम पाने का सबसे सरल और सबसे व्यावहारिक उत्तर दिया गया है:

var actionName = RouteData.Values["action"];
var controllerName = RouteData.Values["controller"];

या

string actionName = RouteData.Values["action"].ToString();
string controllerName = RouteData.Values["controller"].ToString();

Asp.net mvc 5 के साथ परीक्षणों के ऊपर कोड।


2

GetDefaults () विधि के अंदर इसे अपने आधार नियंत्रक में जोड़ें

    protected override void OnActionExecuting(ActionExecutingContext filterContext)
    {
         GetDefaults();
         base.OnActionExecuting(filterContext);
    }

    private void GetDefaults()
    {
    var actionName = filterContext.ActionDescriptor.ActionName;
    var controllerName = filterContext.ActionDescriptor.ControllerDescriptor.ControllerName;
    }

अपने नियंत्रकों को बेसकंट्रोलर पर लागू करें

आंशिक दृश्य _Breadcrumb.cshtml जोड़ें और इसे सभी आवश्यक पृष्ठों में @ Html.Partial ("_ Breadcrumb") के साथ जोड़ें

_Breadcrumb.cshtml

<span>
    <a href="../@ViewData["controllerName"]">
        @ViewData["controllerName"]
    </a> > @ViewData["actionName"]
</span>

(1): क्या यह अभी भी MVC5 के भीतर सबसे आम तरीकों में से एक है? (२) आपको अपना filterContextचर कहाँ से मिलेगा GetDefaults()?
१५:०५ पर chriszo111

1

आप किसी भी चर की तरह एक्शन से कंट्रोलर नाम या एक्शन नाम प्राप्त कर सकते हैं। वे सिर्फ विशेष (नियंत्रक और क्रिया) हैं और पहले से ही परिभाषित हैं इसलिए आपको उन्हें कुछ भी विशेष करने की आवश्यकता नहीं है सिवाय आपको यह बताने के कि आपको उनकी आवश्यकता है।

public string Index(string controller,string action)
   {
     var names=string.Format("Controller : {0}, Action: {1}",controller,action);
     return names;
   }

या आप उनमें से दो और अपने कस्टम डेटा प्राप्त करने के लिए अपने मॉडलों में नियंत्रक, कार्रवाई शामिल कर सकते हैं।

public class DtoModel
    {
        public string Action { get; set; }
        public string Controller { get; set; }
        public string Name { get; set; }
    }

public string Index(DtoModel baseModel)
    {
        var names=string.Format("Controller : {0}, Action: {1}",baseModel.Controller,baseModel.Action);
        return names;
    }

1

यह मेरे लिए (अब तक) अच्छी तरह से काम करने लगता है, यह भी काम करता है यदि आप विशेषता रूटिंग का उपयोग कर रहे हैं।

public class BaseController : Controller
{
    protected string CurrentAction { get; private set; }
    protected string CurrentController { get; private set; }

    protected override void Initialize(RequestContext requestContext)
    {
        this.PopulateControllerActionInfo(requestContext);
    }

    private void PopulateControllerActionInfo(RequestContext requestContext)
    {
        RouteData routedata = requestContext.RouteData;

        object routes;

        if (routedata.Values.TryGetValue("MS_DirectRouteMatches", out routes))
        {
            routedata = (routes as List<RouteData>)?.FirstOrDefault();
        }

        if (routedata == null)
            return;

        Func<string, string> getValue = (s) =>
        {
            object o;
            return routedata.Values.TryGetValue(s, out o) ? o.ToString() : String.Empty;
        };

        this.CurrentAction = getValue("action");
        this.CurrentController = getValue("controller");
    }
}

1

ToString()कॉल उपयोग की आवश्यकता को दूर करने के लिए

string actionName = ControllerContext.RouteData.GetRequiredString("action");
string controllerName = ControllerContext.RouteData.GetRequiredString("controller");

1

कार्रवाई और नियंत्रक के नाम के लिए OnActionExecuting में दी गई लाइनों का उपयोग करें।

string ActionName = this.ControllerContext.RouteData.Values ​​["action"]। ToString ();

स्ट्रिंग नियंत्रक नाम = यह। कंट्रोलरकोनटेक्स्ट.रूटीडेटा। वैल्यू ["कंट्रोलर"]। ToString ();


-8

कुछ सरल क्यों नहीं है?

बस कॉल करें Request.Path, यह "/" द्वारा पृथक स्ट्रिंग लौटा देगा

और फिर आप .Split('/')[1]नियंत्रक नाम प्राप्त करने के लिए उपयोग कर सकते हैं ।

यहां छवि विवरण दर्ज करें


1
-1: आपके कोड के साथ, उप-स्तरीय अनुप्रयोगों को केवल अनदेखा किया जाता है (जैसे:) http://www.example.com/sites/site1/controllerA/actionB/। MVC एपीआई के लिए राउटिंग के लिए एक गुच्छा प्रदान करता है, इसलिए आपको URL को फिर से पार्स करने की आवश्यकता क्यों है?
T-moty

पहिया और इसके अलावा, एक मजबूत सुदृढीकरण के साथ फिर से क्यों बनाया जाए? यह सभी मामलों के लिए काम नहीं करता है।
jstuardo

सबफ़ोल्डर्स से ऐसिड्स, असली समस्या यह है कि आप अपने मार्गों को अनुकूलित कर सकते हैं ताकि वे हमेशा नहीं रहेंगेcontroller/action
drzaus
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.