2012-02-10 8 views
12

एक एमवीसी (2) उपयोगकर्ता नियंत्रण के अंदर से, मैं सभी मार्ग मानों के माध्यम से लूप करना चाहता हूं।मैं सभी मार्गों के माध्यम से कैसे लूप कर सकता हूं?

/user/... 
/account/... 

अर्थात मूल्यों उपयोगकर्ता, खाता:

UserController 
AccountController 

मैं मूल्यों का एक संग्रह की तरह यूआरएल में दिखाई देगा की जरूरत है:

तो अगर मैं की तरह नियंत्रकों की है।

मैं इसे कैसे प्राप्त कर सकता हूं?

मैंने रूटटेबल्स की कोशिश की लेकिन इसे समझ नहीं पाया।

+0

आप रूट मूल्यों क्या मतलब है ..? – MethodMan

+0

क्या आपके पास एक पेड़/ग्राफ है? – Adrian

+2

रूटटेबल वास्तव में देखने के लिए जगह है ... उसने कहा, हम इसे दूसरी तरफ करते हैं: हम मार्गों का विज्ञापन करने के लिए विशेषताओं का उपयोग करते हैं, और प्रतिबिंब के माध्यम से मार्ग-तालिका का निर्माण करते हैं - और हम निश्चित रूप से उस प्रतिबिंब को चला सकते हैं मार्गों की सूची –

उत्तर

15

ओह, वास्तव में एक घंटे के लिए व्यस्त रहने के लिए एक अच्छा सवाल है। आवश्यक कार्यक्षमता प्राप्त करने के लिए, हमें एमवीसी स्रोत और प्रतिबिंबों के थोड़ा सा हुक करने की आवश्यकता है।

  1. डिफ़ॉल्ट रूट के नाम से उपलब्ध नहीं हैं, तो हम RouteData टोकन में मार्ग का नाम बचाने के लिए एक मार्ग संग्रह विस्तार लिखने के लिए की जरूरत है।

    public static Route MapRouteWithName(this RouteCollection routes,string name, string url, object defaults=null, object constraints=null) 
    { 
    
    Route route = routes.MapRoute(name, url, defaults, constraints); 
    route.DataTokens = new RouteValueDictionary(); 
    route.DataTokens.Add("RouteName", name); 
    return route; 
    } 
    
  2. पिछले विस्तार

    routes.MapRouteWithName(
          "Default", // Route name 
          "{controller}/{action}/{id}", // URL with parameters 
          new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults 
         ); 
    
  3. संशोधित MVC PathHelper एक छोटा सा आह्वान करने के लिए Global.asax maproute कॉल को संशोधित करें। (परियोजना में इस सहायक शामिल करें)

    using System; 
    using System.Collections.Specialized; 
    using System.Web; 
    
    public static class PathHelpers 
    { 
    
    // this method can accept an app-relative path or an absolute path for contentPath 
    public static string GenerateClientUrl(HttpContextBase httpContext, string contentPath) 
    { 
        if (String.IsNullOrEmpty(contentPath)) 
        { 
         return contentPath; 
        } 
    
        // many of the methods we call internally can't handle query strings properly, so just strip it out for 
        // the time being 
        string query; 
        contentPath = StripQuery(contentPath, out query); 
    
        return GenerateClientUrlInternal(httpContext, contentPath) + query; 
    } 
    
    private static string GenerateClientUrlInternal(HttpContextBase httpContext, string contentPath) 
    { 
        if (String.IsNullOrEmpty(contentPath)) 
        { 
         return contentPath; 
        } 
    
        // can't call VirtualPathUtility.IsAppRelative since it throws on some inputs 
        bool isAppRelative = contentPath[0] == '~'; 
        if (isAppRelative) 
        { 
         string absoluteContentPath = VirtualPathUtility.ToAbsolute(contentPath, httpContext.Request.ApplicationPath); 
         string modifiedAbsoluteContentPath = httpContext.Response.ApplyAppPathModifier(absoluteContentPath); 
         return GenerateClientUrlInternal(httpContext, modifiedAbsoluteContentPath); 
        } 
    
        string relativeUrlToDestination = MakeRelative(httpContext.Request.Path, contentPath); 
        string absoluteUrlToDestination = MakeAbsolute(httpContext.Request.RawUrl, relativeUrlToDestination); 
        return absoluteUrlToDestination; 
    } 
    
    public static string MakeAbsolute(string basePath, string relativePath) 
    { 
        // The Combine() method can't handle query strings on the base path, so we trim it off. 
        string query; 
        basePath = StripQuery(basePath, out query); 
        return VirtualPathUtility.Combine(basePath, relativePath); 
    } 
    
    public static string MakeRelative(string fromPath, string toPath) 
    { 
        string relativeUrl = VirtualPathUtility.MakeRelative(fromPath, toPath); 
        if (String.IsNullOrEmpty(relativeUrl) || relativeUrl[0] == '?') 
        { 
         // Sometimes VirtualPathUtility.MakeRelative() will return an empty string when it meant to return '.', 
         // but links to {empty string} are browser dependent. We replace it with an explicit path to force 
         // consistency across browsers. 
         relativeUrl = "./" + relativeUrl; 
        } 
        return relativeUrl; 
    } 
    
    private static string StripQuery(string path, out string query) 
    { 
        int queryIndex = path.IndexOf('?'); 
        if (queryIndex >= 0) 
        { 
         query = path.Substring(queryIndex); 
         return path.Substring(0, queryIndex); 
        } 
        else 
        { 
         query = null; 
         return path; 
        } 
    } 
    
    } 
    
  4. नियंत्रक

    में कुछ सहायक विधियां जोड़ें
  5. अब हम कुछ प्रतिबिंब तर्क लिख सकते हैं नियंत्रकों, कार्यों और routenames पढ़ने के लिए।

    Dictionary<string, List<string>> controllersAndActions = new Dictionary<string, List<string>>(); 
    
    // Get all the controllers 
    var controllers = Assembly.GetExecutingAssembly().GetTypes().Where(t => typeof(Controller).IsAssignableFrom(t)); 
    
    foreach (var controller in controllers) 
    { 
        List<string> actions = new List<string>(); 
        //Get all methods without HttpPost and with return type action result 
        var methods = controller.GetMethods().Where(m => typeof(ActionResult).IsAssignableFrom(m.ReturnType)).Where(a=>!a.GetCustomAttributes(typeof(HttpPostAttribute),true).Any()); 
        methods.ToList().ForEach(a => { 
         actions.Add(a.Name); 
        }); 
        var controllerName = controller.Name; 
        if (controllerName.EndsWith("Controller")) 
        { 
         var nameLength = controllerName.Length - "Controller".Length; 
         controllerName = controllerName.Substring(0, nameLength); 
        } 
        controllersAndActions.Add(controllerName, actions); 
    } 
    List<string> allowedRoutes = new List<string>(); 
    
    var routeNames = RouteTable.Routes.Where(o=>o.GetRouteData(this.HttpContext)!=null).Select(r=>r.GetRouteData(this.HttpContext).DataTokens["RouteName"].ToString()); 
    foreach (var cName in controllersAndActions) 
    { 
        foreach (var aName in cName.Value) 
        { 
         foreach (var item in routeNames) 
         { 
          allowedRoutes.Add(GenerateUrl(item, aName, cName.Key, RouteTable.Routes, this.Request.RequestContext)); 
         } 
        } 
    
    } 
    
  6. अंक याद करने के लिए: मार्ग में आप किसी भी डिफ़ॉल्ट मानकों को परिभाषित किया है, तो उन नियंत्रक के लिए URL और कार्रवाई खाली हो जाएगा। जैसे ऊपर के उदाहरण में "/ घर/सूचकांक" के रूप "/"

  7. डाउनलोड नमूना आवेदन दिखाया जाएगा Link To Download

    List item

+0

वोआ। विशाल जवाब, दोस्त! – Almo

+0

हां, एक घंटे के आसपास एक रास्ता मिला – Manas

+0

बहुत बढ़िया! मुझे लगता है कि यह आवश्यक होगा लेकिन इसे लिखना नहीं चाहता था। मुझे पता है कि एकमात्र अन्य समाधान FubuMVC का उपयोग करना है। :) http://codebetter.com/jeremymiller/2010/01/04/fubumvc-diagnostics-sneak-peek/ – Ryan

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