2012-04-20 31 views
9

pregunta muy simple, pero no pude encontrar una respuesta para esto:ASP .Net MVC enrutamiento: Url únicamente con ID de cadena

tengo el defecto {controller}/{action}/{id} patrón en mi Global.asax.

necesito también algo me va a dar algo así como www.example.com/microsoft o www.example.com/apple mientras que Microsoft y Apple están id almacenan en la base de datos. El uso del patrón predeterminado sería: www.example.com/brands/detail/microsoft

¿Alguna idea de cómo debe ser el patrón? intenté: {id} y configuré el controlador y la acción a brands y detail funciona para servir a mi necesidad pero arruina el resto de patrones.

gracias

+0

no parece posible, ya que no puede decirle a www.example.com/apple desde www.example.com/login si primero es un Id. de marca y el segundo es el Controlador nombre. A menos que escriba su propio proveedor de enrutamiento personalizado y verifique si esa parte debe ser la marca o el nombre del controlador.Pero eso sería demasiado complicado para la mayoría de los casos para un enrutador ... – xandy

Respuesta

5

Tu pedido es importante. Por lo tanto, cree una primera definición de ruta que maneje todos los controladores disponibles y luego mencione uno que manejará el resto de las solicitudes. No va a manejar el tipo www.yousite.com/apple de solicitud

routes.MapRoute("Default", // Route name 
        "{controller}/{action}/{id}", // URL with parameters 
        new { controller = "Home", action = "Index", id = "" }, 
        new { controller = new FromValuesListConstraint("Home", "Account","OtherOne") } 
       ); 

// to handle personalize user url 
routes.MapRoute("user","{url}", new {controller="Home",action="Profile",url = "" }); 

Ahora crear una nueva clase llamada FromValuesListContraint, que hereda de IRouteConstraint

public class FromValuesListConstraint : IRouteConstraint 
{ 
    private string[] _values; 

    public FromValuesListConstraint(params string[] values) 
    { 
     this._values = values; 
    } 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, 
    RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     // Get the value called "parameterName" from the 
     // RouteValueDictionary called "value" 

     string value = values[parameterName].ToString(); 

     // Return true is the list of allowed values contains 
     // this value. 

     for (int i = 0; i < _values.Length; i++) 
      if (SContains(_values[i], value, StringComparison.OrdinalIgnoreCase)) 
       return true; 

     return false; 
    }  

    public bool SContains(string source, string toCheck, StringComparison comp) 
    { 
     return source.IndexOf(toCheck, comp) >= 0; 
    } 
} 

que su método de acción Profile en Inicio leer el valor del parámetro y obtener datos de su base de datos.

public ActionResult Profile(string url) 
{ 
    //url variable will have apple or microsoft . You may get data from db and return a view now. 
} 

Así que cuando llega una solicitud, se comprobará si se trata de un controlador disponible (que usted pasó en el constructor de la clase FromValuesListContraint en su primera definición de la ruta), si está disponible, entonces irá por que el enrutamiento, de lo contrario, irá por la ruta general (predeterminada) mencionada como la segunda ruta.

En este ejemplo, Inicio, Cuenta y OtherOnes son mis controladores disponibles. cada vez que agrega un nuevo controlador a su proyecto, desea agregarlo al constructor del constructor de clase FromValuesListConstraint.

¡Simplemente diciendo que funciona como atrapar una excepción específica y va a la excepción general si no se detecta ninguno! :) (solo un ejemplo para entender)

+0

hasta ahora me gusta la idea, intentaré implementarla. gracias – dritterweg

+0

fue bueno ... Implementé mi url de enrutamiento como este nuevo {Controlador = "Inicio", acción = "Índice", id = ""} Puedo obtener URL como: http: // localhost: 53045/Accounts/chjnvd780 . ¿Tiene idea de por qué mi modelstate.isvalid obtiene el error? está mostrando El valor 'chjnvd780' no es válido para Id. ¿Tiene idea de cómo resolverlo? – Cherry

6

yo sugeriría una ruta separada con una restricción de que el ID sea no puede coincidir con uno de los controladores o debe coincidir con uno de los identificadores en la base de datos. Liste antes de la ruta predeterminada para que coincida primero, si se cumplen las calificaciones.

Ejemplo usando una expresión regular simple para una restricción fija, aunque probablemente desee crear una restricción personalizada derivada de IRouteConstraint que limita los valores dinámicamente.

routes.MapRoute(
    "Brands", 
    "{id}", 
    new { controller = "brand", action = "detail" }, 
    new { id = "^(Microsoft)|(Apple)$" } 
); 

Es posible que desee ver en http://stephenwalther.com/blog/archive/2008/08/07/asp-net-mvc-tip-30-create-custom-route-constraints.aspx para obtener más ideas.

Cuestiones relacionadas