ASP.NET MVC रूटिंग वाया विधि विशेषताएँ [बंद]


80

में StackOverflow पॉडकास्ट # 54 , जेफ का उल्लेख है वे रजिस्टर StackOverflow में अपने यूआरएल मार्गों विधि है कि हैंडल मार्ग ऊपर एक विशेषता के माध्यम से codebase। एक अच्छी अवधारणा की तरह लगता है (के साथ है कि फिल Haack मार्ग प्राथमिकताओं के बारे में लाया)।

क्या कोई ऐसा करने के लिए कुछ नमूना प्रदान कर सकता है?

इसके अलावा, रूटिंग की इस शैली का उपयोग करने के लिए कोई "सर्वोत्तम अभ्यास"?

जवाबों:


62

अद्यतन : यह कोडप्लेक्स पर पोस्ट किया गया है। पूर्ण स्रोत कोड और प्री-संकलित असेंबली डाउनलोड के लिए हैं। मेरे पास अभी तक साइट पर प्रलेखन पोस्ट करने का समय नहीं है, इसलिए इस एसओ पोस्ट को अभी के लिए सहना होगा।

अद्यतन : मैंने 1) रूट ऑर्डरिंग, 2) रूट पैरामीटर बाधाओं, और 3) रूट पैरामीटर डिफ़ॉल्ट मानों को संभालने के लिए कुछ नई विशेषताओं को जोड़ा। नीचे दिया गया पाठ इस अद्यतन को दर्शाता है।

मैंने वास्तव में अपने एमवीसी प्रोजेक्ट्स के लिए कुछ ऐसा किया है (मुझे नहीं पता कि जेफ स्टैकओवरफ्लो के साथ कैसा कर रहा है)। मैंने कस्टम विशेषताओं का एक सेट परिभाषित किया: UrlRoute, UrlRouteParameterConstraint, UrlRouteParameterDefault। वे MVC कंट्रोलर एक्शन मेथड्स में अटैच किए जा सकते हैं ताकि रूट, अड़चनें और डिफॉल्ट उनके लिए खुद ही बाध्य हो जाएं।

उदाहरण का उपयोग:

(ध्यान दें कि यह उदाहरण कुछ आकस्मिक है लेकिन यह सुविधा प्रदर्शित करता है)

public class UsersController : Controller
{
    // Simple path.
    // Note you can have multiple UrlRoute attributes affixed to same method.
    [UrlRoute(Path = "users")]
    public ActionResult Index()
    {
        return View();
    }

    // Path with parameter plus constraint on parameter.
    // You can have multiple constraints.
    [UrlRoute(Path = "users/{userId}")]
    [UrlRouteParameterConstraint(Name = "userId", Regex = @"\d+")]
    public ActionResult UserProfile(int userId)
    {
        // ...code omitted

        return View();
    }

    // Path with Order specified, to ensure it is added before the previous
    // route.  Without this, the "users/admin" URL may match the previous
    // route before this route is even evaluated.
    [UrlRoute(Path = "users/admin", Order = -10)]
    public ActionResult AdminProfile()
    {
        // ...code omitted

        return View();
    }

    // Path with multiple parameters and default value for the last
    // parameter if its not specified.
    [UrlRoute(Path = "users/{userId}/posts/{dateRange}")]
    [UrlRouteParameterConstraint(Name = "userId", Regex = @"\d+")]
    [UrlRouteParameterDefault(Name = "dateRange", Value = "all")]
    public ActionResult UserPostsByTag(int userId, string dateRange)
    {
        // ...code omitted

        return View();
    }

UrlRouteAttribute की परिभाषा:

/// <summary>
/// Assigns a URL route to an MVC Controller class method.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteAttribute : Attribute
{
    /// <summary>
    /// Optional name of the route.  If not specified, the route name will
    /// be set to [controller name].[action name].
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Path of the URL route.  This is relative to the root of the web site.
    /// Do not append a "/" prefix.  Specify empty string for the root page.
    /// </summary>
    public string Path { get; set; }

    /// <summary>
    /// Optional order in which to add the route (default is 0).  Routes
    /// with lower order values will be added before those with higher.
    /// Routes that have the same order value will be added in undefined
    /// order with respect to each other.
    /// </summary>
    public int Order { get; set; }
}

UrlRouteParameterConstraintAttribute की परिभाषा:

/// <summary>
/// Assigns a constraint to a route parameter in a UrlRouteAttribute.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteParameterConstraintAttribute : Attribute
{
    /// <summary>
    /// Name of the route parameter on which to apply the constraint.
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Regular expression constraint to test on the route parameter value
    /// in the URL.
    /// </summary>
    public string Regex { get; set; }
}

UrlRouteParameterDefaultAttribute की परिभाषा:

/// <summary>
/// Assigns a default value to a route parameter in a UrlRouteAttribute
/// if not specified in the URL.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteParameterDefaultAttribute : Attribute
{
    /// <summary>
    /// Name of the route parameter for which to supply the default value.
    /// </summary>
    public string Name { get; set; }

    /// <summary>
    /// Default value to set on the route parameter if not specified in the URL.
    /// </summary>
    public object Value { get; set; }
}

Global.asax.cs में परिवर्तन:

RouteUtility.RegisterUrlRoutesFromAttribution फ़ंक्शन के लिए एकल कॉल के साथ, कॉल मैप्स मैपआउट में बदलें:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        RouteUtility.RegisterUrlRoutesFromAttributes(routes);
    }

रूट यूटिलिटी की परिभाषा।

पूरा स्रोत कोडप्लेक्स पर है । यदि आपके पास कोई प्रतिक्रिया या बग रिपोर्ट है तो कृपया साइट पर जाएं।


मुझे लगता है कि विशेषताओं के साथ ऐसा करने से मार्ग की कमी और मार्ग की बाधाओं का उपयोग करने से रोकता है ...
निकोलस कैडिलैक

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

3
बहुत अच्छा! हमारा रूटएट्रिब्यूट बहुत हद तक इसी तरह का है, केवल कुछ अतिरिक्त सहायक कार्यक्षमता को जोड़ता है। मुझे मतभेदों का विवरण देते हुए एक उत्तर जोड़ना होगा।
जारोद डिक्सन

1
यह शानदार है। मैं इसे प्यार कर रहा हूँ।
बोउर्सकिंकूपा

1
यह भी खूब रही! मैं थोड़ी देर के लिए MvcContrib का उपयोग कर रहा हूं और मुझे पता नहीं था कि यह वहां था। आपने अपनी मूल पोस्ट में उल्लेख किया है कि आपके पास इसे दस्तावेज करने का समय नहीं था। क्या ये अब भी एक मामला है? MvcContrib डॉक्स में कम से कम इसका उल्लेख जैसा लगता है, बहुत उपयोगी होगा ताकि डेवलपर्स कम से कम यह जान सकें कि यह वहाँ है। धन्यवाद!
टोड मेनियर

44

तुम भी कोशिश कर सकते हैं AttributeRouting , जिसमें से उपलब्ध है GitHub या के माध्यम से nuget

यह एक बेशर्म प्लग है, जैसा कि मैं परियोजना लेखक हूं। लेकिन अगर मैं इसका उपयोग करके बहुत खुश नहीं हूँ तो खतरा है। आप भी हो सकते हैं। गिथब रिपॉजिटरी विकी में बहुत सारे प्रलेखन और नमूना कोड हैं ।

इस लाइब्रेरी के साथ, आप बहुत कुछ कर सकते हैं:

  • GET, POST, PUT और DELETE विशेषताओं के साथ अपने कार्यों को सजाएं।
  • एक एकल कार्रवाई के लिए कई मार्गों को मैप करें, उन्हें ऑर्डर प्रॉपर्टी के साथ ऑर्डर करें।
  • विशेषताओं का उपयोग करते हुए मार्ग की चूक और बाधाओं को निर्दिष्ट करें।
  • एक साधारण के साथ वैकल्पिक परम निर्दिष्ट करें? पैरामीटर नाम से पहले टोकन।
  • नामित मार्गों का समर्थन करने के लिए मार्ग का नाम निर्दिष्ट करें।
  • नियंत्रक या आधार नियंत्रक पर MVC क्षेत्रों को परिभाषित करें।
  • नियंत्रक या आधार नियंत्रक पर लागू रूट उपसर्गों का उपयोग करके अपने मार्गों को एक साथ समूह या घोंसला करें।
  • विरासत का समर्थन करते हैं।
  • किसी नियंत्रक के लिए, और नियंत्रक और आधार नियंत्रक के बीच परिभाषित मार्गों के बीच मार्गों की पूर्ववर्ती स्थिति निर्धारित करें।
  • लोअरकेस आउटबाउंड यूआरएल को स्वचालित रूप से उत्पन्न करें।
  • अपने स्वयं के कस्टम मार्ग सम्मेलनों को परिभाषित करें और उन्हें बॉयलरप्लेट विशेषताओं (रेस्टफुल स्टाइल के बारे में सोचें) के बिना नियंत्रक के भीतर क्रियाओं के लिए मार्ग उत्पन्न करने के लिए एक नियंत्रक पर लागू करें।
  • आपूर्ति किए गए HttpHandler का उपयोग करके अपने मार्गों को डीबग करें।

मुझे यकीन है कि कुछ और चीजें हैं जिन्हें मैं भूल रहा हूं। इसकी जांच - पड़ताल करें। यह नगेट के माध्यम से स्थापित करने के लिए दर्द रहित है।

नोट: 4/16/12 के अनुसार, एट्रीब्यूटाउटिंग नए वेब एपीआई बुनियादी ढांचे का भी समर्थन करता है। बस अगर आप किसी ऐसी चीज की तलाश कर रहे हैं जो आपको संभाल सकती है। धन्यवाद सबकुमारन !


10
यह परियोजना उल्लिखित अन्य विकल्पों की तुलना में अधिक परिपक्व (बेहतर प्रलेखन, अधिक विशेषता, पूर्ण परीक्षण सूट) लगती है
डेविड लांग

3
मैं सहमत हूं, यह वह सब कुछ करने के लिए लगता है जो आप संभवतः चाहते थे, और अच्छे उदाहरण प्रलेखन के साथ।
माइक चैंबरलेन

3
आपका बहुत बहुत धन्यवाद। मैं खुशी से इस समाधान का उपयोग कर रहा हूं और इसने मेरे सभी रूटिंग संघर्षों, अस्पष्टता और भ्रम को हल किया है।
वलमास

3
हे स्पॉट, आपको अपने गिटबब पेज पर उपरोक्त बुलेट पॉइंट्स लिखना चाहिए, क्योंकि मुझे यह एसओ पोस्ट मिला क्योंकि मैं अधिक विवरण के लिए शिकार पर था :)
गोनेले

2
सिर्फ शैतानों की वकालत करने के लिए, क्या आपके मार्गों को एक ही स्थान पर घोषित करने का कोई लाभ है? जैसे हम कुछ भी खो देते हैं, या इस पद्धति पर स्विच करने वाले किसी भी फैशन में सीमित हैं?
गोनैले

9

1. RiaLibrary.eb.dll डाउनलोड करें और इसे अपने ASP.NET MVC वेबसाइट प्रोजेक्ट में देखें

2. [नियंत्रक] विशेषता के साथ सजावटी नियंत्रक तरीके:

public SiteController : Controller
{
    [Url("")]
    public ActionResult Home()
    {
        return View();
    }

    [Url("about")]
    public ActionResult AboutUs()
    {
        return View();
    }

    [Url("store/{?category}")]
    public ActionResult Products(string category = null)
    {
        return View();
    }
}

BTW, '?' साइन इन करें {{? category} ’पैरामीटर का मतलब है कि यह वैकल्पिक है। आपको इसे रूट डिफॉल्ट में स्पष्ट रूप से निर्दिष्ट करने की आवश्यकता नहीं होगी, जो इसके बराबर है:

routes.MapRoute("Store", "store/{category}",
new { controller = "Store", action = "Home", category = UrlParameter.Optional });

3. अद्यतन Global.asax.cs फ़ाइल

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoutes(); // This does the trick
    }

    protected void Application_Start()
    {
        RegisterRoutes(RouteTable.Routes);
    }
}

चूक और बाधाओं को कैसे निर्धारित करें? उदाहरण:

public SiteController : Controller
{
    [Url("admin/articles/edit/{id}", Constraints = @"id=\d+")]
    public ActionResult ArticlesEdit(int id)
    {
        return View();
    }

    [Url("articles/{category}/{date}_{title}", Constraints =
         "date=(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])")]
    public ActionResult Article(string category, DateTime date, string title)
    {
        return View();
    }
}

ऑर्डर कैसे सेट करें? उदाहरण:

[Url("forums/{?category}", Order = 2)]
public ActionResult Threads(string category)
{
    return View();
}

[Url("forums/new", Order = 1)]
public ActionResult NewThread()
{
    return View();
}

1
बहुत अच्छा! मैं विशेष रूप से {?param}वैकल्पिक मापदंडों के लिए नामकरण पसंद करता हूं ।
जारोड डिक्सन

3

यह पोस्ट केवल डीएसओ के उत्तर का विस्तार करने के लिए है।

मेरे मार्गों को विशेषताओं में परिवर्तित करते समय, मुझे ActionName विशेषता को संभालने की आवश्यकता थी। तो GetRouteParamsFromAttribute में:

ActionNameAttribute anAttr = methodInfo.GetCustomAttributes(typeof(ActionNameAttribute), false)
    .Cast<ActionNameAttribute>()
    .SingleOrDefault();

// Add to list of routes.
routeParams.Add(new MapRouteParams()
{
    RouteName = routeAttrib.Name,
    Path = routeAttrib.Path,
    ControllerName = controllerName,
    ActionName = (anAttr != null ? anAttr.Name : methodInfo.Name),
    Order = routeAttrib.Order,
    Constraints = GetConstraints(methodInfo),
    Defaults = GetDefaults(methodInfo),
});

इसके अलावा, मुझे मार्ग का नामकरण उपयुक्त नहीं लगा। नाम डायनामिक रूप से कंट्रोलरनेम.आउट.नाम के साथ बनाया गया है। लेकिन मेरे रूट के नाम कंट्रोलर क्लास में कास्ट स्ट्रिंग्स हैं और मैं उन कॉस्ट का इस्तेमाल उरल.रूट यूअर्ल भी करता हूं। इसलिए मुझे वास्तव में मार्ग का वास्तविक नाम होने के लिए मार्ग नाम की आवश्यकता है।

एक और चीज जो मैं करूंगा वह है डिफाल्ट और अड़चन वाले गुणों को एट्रीब्यूटटर्ेट्स.प्रेमेट में बदलना।


हाँ, मैं मार्ग नामकरण व्यवहार पर दोलन करता हूँ। इसका शायद सबसे अच्छा है कि आपने क्या किया है, बस विशेषता में व्हाट्स का उपयोग करें-या इसे शून्य बना दें। अच्छा विचार डिफ़ॉल्ट / बाधाओं को स्वयं पराम पर रख रहा है। मैं शायद बदलाव को बेहतर ढंग से प्रबंधित करने के लिए कुछ बिंदु पर कोडप्लेक्स पर पोस्ट करूंगा।
DSO

0

मैंने इन दोनों दृष्टिकोणों को फ्रेंकस्टीनियन संस्करण में किसी भी व्यक्ति के लिए जोड़ दिया है जो इसे चाहता है। (मुझे वैकल्पिक पैरामेशन नोटेशन पसंद आया, लेकिन यह भी सोचा कि उन्हें डिफ़ॉल्ट / बाधाओं से अलग होना चाहिए बजाय सभी को एक में मिलाने के)।

http://github.com/djMax/AlienForce/tree/master/Utilities/Web/


0

मैं एक AsyncController का उपयोग करते हुए asp.net mvc 2 में काम करने वाले ITCloud रूटिंग को प्राप्त करने की आवश्यकता है - ऐसा करने के लिए, स्रोत में केवल रूट यूटिलिटी.केएस क्लास को संपादित करें और recompile। आपको लाइन 98 पर कार्रवाई के नाम से "पूर्ण" बंद करना होगा

// Add to list of routes.
routeParams.Add(new MapRouteParams()
{
    RouteName = String.IsNullOrEmpty(routeAttrib.Name) ? null : routeAttrib.Name,
    Path = routeAttrib.Path,
    ControllerName = controllerName,
    ActionName = methodInfo.Name.Replace("Completed", ""),
    Order = routeAttrib.Order,
    Constraints = GetConstraints(methodInfo),
    Defaults = GetDefaults(methodInfo),
    ControllerNamespace = controllerClass.Namespace,
});

फिर, AsyncController में, परिचित UrlRouteऔर UrlRouteParameterDefaultविशेषताओं के साथ XXXXCompleted ActionResult को सजाएं :

[UrlRoute(Path = "ActionName/{title}")]
[UrlRouteParameterDefault(Name = "title", Value = "latest-post")]
public ActionResult ActionNameCompleted(string title)
{
    ...
}

आशा है कि एक ही मुद्दे के साथ किसी की मदद करता है।


FYI करें, कन्वेंशन के लिए MVC संबंधित विशेषताएँ ActionNameAsync विधि पर है न कि ActionNameCompleted विधि।
एरव वाल्टर

धन्यवाद - इसका एहसास नहीं हुआ।
तिमोग
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.