asp.net asp.net-mvc routes action asp.net-mvc-routing

ASP.Net MVC Segmentos de manejo con ruta



asp.net-mvc routes (1)

Soy nuevo en ASP.Net MVC y enfrento un problema. Aquí está.

routes.MapRoute( "SearchResults",// Route name "{controller}/{action}/{category}/{manufacturer}/{attribute}", new { controller = "Home", action = "CategoryProducts", category = UrlParameter.Optional, manufacturer = UrlParameter.Optional, attribute = UrlParameter.Optional } );

Y aquí está mi método controlador.

public ActionResult CategoryProducts(string category, string manufacturer, string attribute) { string[] categoryParameter = category.Split(''_''); . . . return View(); }

cuando llego a la URL siempre obtengo un valor nulo en el parámetro de categoría

http://localhost:50877/Home/CategoryProducts/c_50_ShowcasesDisplays

Me sale este error

Object reference not set to an instance of an object

Como puedo solucionar este problema. Necesito extraer la identificación del segmento y usarla. Del mismo modo, necesito procesar el fabricante y las cadenas de atributos también.

Una cosa más

¿Cómo puedo hacer que mi función obtenga al menos un parámetro independientemente del orden? Quiero decir que quiero hacer funciones como esa, puedo manejar categoría o fabricante o atributos o categoría + fabricante y todas las combinaciones /


Un marcador de posición (como {category} ) actúa como una variable: puede contener cualquier valor. El marco debe ser capaz de comprender qué significan los parámetros en la URL. Puedes hacer esto de tres maneras:

  1. Proporcionarlos en un orden específico y para un número específico de segmentos.
  2. Póngalos en la cadena de consulta para que tenga pares de nombre / valor para identificar cuáles son
  3. Haga una serie de rutas con segmentos literales para proporcionar nombres para identificar cuáles son los parámetros

Aquí hay un ejemplo de la opción # 3. Es un poco complicado en comparación con el uso de parámetros de cadena de consulta, pero ciertamente es posible siempre que proporcione algún tipo de identificador para cada segmento de ruta.

I Extensiones numerables

Esto agrega compatibilidad con LINQ para poder obtener todas las permutaciones posibles de los valores de los parámetros.

using System; using System.Collections.Generic; using System.Linq; public static class IEnumerableExtensions { // Can be used to get all permutations at a certain level // Source: http://.com/questions/127704/algorithm-to-return-all-combinations-of-k-elements-from-n#1898744 public static IEnumerable<IEnumerable<T>> Combinations<T>(this IEnumerable<T> elements, int k) { return k == 0 ? new[] { new T[0] } : elements.SelectMany((e, i) => elements.Skip(i + 1).Combinations(k - 1).Select(c => (new[] { e }).Concat(c))); } // This one came from: http://.com/questions/774457/combination-generator-in-linq#12012418 private static IEnumerable<TSource> Prepend<TSource>(this IEnumerable<TSource> source, TSource item) { if (source == null) throw new ArgumentNullException("source"); yield return item; foreach (var element in source) yield return element; } public static IEnumerable<IEnumerable<TSource>> Permutations<TSource>(this IEnumerable<TSource> source) { if (source == null) throw new ArgumentNullException("source"); var list = source.ToList(); if (list.Count > 1) return from s in list from p in Permutations(list.Take(list.IndexOf(s)).Concat(list.Skip(list.IndexOf(s) + 1))) select p.Prepend(s); return new[] { list }; } }

Extensiones RouteCollection

Extendemos el método de extensión MapRoute , agregando la capacidad de agregar un conjunto de rutas para que coincida con todas las permutaciones posibles de la URL.

using System; using System.Collections.Generic; using System.Web.Mvc; using System.Web.Routing; public static class RouteCollectionExtensions { public static void MapRoute(this RouteCollection routes, string url, object defaults, string[] namespaces, string[] optionalParameters) { MapRoute(routes, url, defaults, null, namespaces, optionalParameters); } public static void MapRoute(this RouteCollection routes, string url, object defaults, object constraints, string[] namespaces, string[] optionalParameters) { if (routes == null) { throw new ArgumentNullException("routes"); } if (url == null) { throw new ArgumentNullException("url"); } AddAllRoutePermutations(routes, url, defaults, constraints, namespaces, optionalParameters); } private static void AddAllRoutePermutations(RouteCollection routes, string url, object defaults, object constraints, string[] namespaces, string[] optionalParameters) { // Start with the longest routes, then add the shorter ones for (int length = optionalParameters.Length; length > 0; length--) { foreach (var route in GetRoutePermutations(url, defaults, constraints, namespaces, optionalParameters, length)) { routes.Add(route); } } } private static IEnumerable<Route> GetRoutePermutations(string url, object defaults, object constraints, string[] namespaces, string[] optionalParameters, int length) { foreach (var combination in optionalParameters.Combinations(length)) { foreach (var permutation in combination.Permutations()) { yield return GenerateRoute(url, permutation, defaults, constraints, namespaces); } } } private static Route GenerateRoute(string url, IEnumerable<string> permutation, object defaults, object constraints, string[] namespaces) { var newUrl = GenerateUrlPattern(url, permutation); var result = new Route(newUrl, new MvcRouteHandler()) { Defaults = CreateRouteValueDictionary(defaults), Constraints = CreateRouteValueDictionary(constraints), DataTokens = new RouteValueDictionary() }; if ((namespaces != null) && (namespaces.Length > 0)) { result.DataTokens["Namespaces"] = namespaces; } return result; } private static string GenerateUrlPattern(string url, IEnumerable<string> permutation) { string result = url; foreach (string param in permutation) { result += "/" + param + "/{" + param + "}"; } System.Diagnostics.Debug.WriteLine(result); return result; } private static RouteValueDictionary CreateRouteValueDictionary(object values) { IDictionary<string, object> dictionary = values as IDictionary<string, object>; if (dictionary != null) { return new RouteValueDictionary(dictionary); } return new RouteValueDictionary(values); } }

Uso

public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( url: "Home/CategoryProducts", defaults: new { controller = "Home", action = "CategoryProducts" }, namespaces: null, optionalParameters: new string[] { "category", "manufacturer", "attribute" }); routes.MapRoute( name: "Default", url: "{controller}/{action}/{id}", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } }

Esto agrega un conjunto completo de rutas para que coincida con los patrones de URL:

Home/CategoryProducts/category/{category}/manufacturer/{manufacturer}/attribute/{attribute} Home/CategoryProducts/category/{category}/attribute/{attribute}/manufacturer/{manufacturer} Home/CategoryProducts/manufacturer/{manufacturer}/category/{category}/attribute/{attribute} Home/CategoryProducts/manufacturer/{manufacturer}/attribute/{attribute}/category/{category} Home/CategoryProducts/attribute/{attribute}/category/{category}/manufacturer/{manufacturer} Home/CategoryProducts/attribute/{attribute}/manufacturer/{manufacturer}/category/{category} Home/CategoryProducts/category/{category}/manufacturer/{manufacturer} Home/CategoryProducts/manufacturer/{manufacturer}/category/{category} Home/CategoryProducts/category/{category}/attribute/{attribute} Home/CategoryProducts/attribute/{attribute}/category/{category} Home/CategoryProducts/manufacturer/{manufacturer}/attribute/{attribute} Home/CategoryProducts/attribute/{attribute}/manufacturer/{manufacturer} Home/CategoryProducts/category/{category} Home/CategoryProducts/manufacturer/{manufacturer} Home/CategoryProducts/attribute/{attribute}

Ahora cuando usa la siguiente URL:

Home/CategoryProducts/category/c_50_ShowcasesDisplays

Se HomeController la acción CategoryProducts en el HomeController . El valor del parámetro de categoría será c_50_ShowcasesDisplays .

También creará la URL correspondiente cuando use ActionLink , RouteLink , Url.Action o UrlHelper .

@Html.ActionLink("ShowcasesDisplays", "CategoryProducts", "Home", new { category = "c_50_ShowcasesDisplays" }, null) // Generates URL /Home/CategoryProducts/category/c_50_ShowcasesDisplays