2012-04-20 12 views
9

domanda molto semplice, ma non riuscivo a trovare una risposta per questo:ASP .Net MVC routing: URL soltanto con ID stringa

ho il difetto {controller}/{action}/{id} modello nel mio global.asax.

Ho bisogno anche qualcosa mi darà qualcosa di simile www.example.com/microsoft o www.example.com/apple mentre Microsoft e Apple sono id memorizzati nel database. L'utilizzo del modello predefinito sarebbe: www.example.com/brands/detail/microsoft

qualsiasi idea di come dovrebbe essere il modello? ho provato: {id} e impostato il controller e l'azione su brands e detail funziona per soddisfare le mie necessità ma rovina tutti gli altri schemi.

grazie

+0

non sembra possibile, dal momento che non è possibile dire www.example.com/apple da www.esempio.com/login se prima è un ID marchio e il secondo è il Controller nome. A meno che non si scriva il proprio provider di routing personalizzato e si controlli se tale parte deve essere di marca o nome del controller.Ma sarebbe troppo complicato per la maggior parte dei casi per un router ... – xandy

risposta

5

L'ordine del tuo itinerario è importante. Quindi creare una prima definizione di percorso che gestisca tutti i controller disponibili e quindi menzionarne una che gestirà il resto delle richieste. Vi si possono gestire il www.yousite.com/apple tipo di richiesta

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 = "" }); 

Ora creare una nuova classe chiamata FromValuesListContraint che eredita da 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; 
    } 
} 

Avere il vostro metodo di azione Profile Home leggere il valore del parametro e ottenere i dati dal vostro Banca dati.

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

Così ogni volta che arriva una richiesta, controllerà se è un controller disponibile (che è stato passato nel costruttore della classe FromValuesListContraint nella tua prima definizione della rotta), se disponibili, andrà per quella instradamento, altrimenti, andrà per la rotta generale (predefinita) menzionata come seconda rotta.

In questo esempio, Home, Account e OtherOnes sono i miei controller disponibili. ogni volta che aggiungi un nuovo controller al tuo progetto, devi aggiungerlo al constrctor del costruttore della classe FromValuesListConstraint.

Semplicemente dicendo che funziona come Cattura alcune eccezioni specifiche e andando all'eccezione generale se nessuna di esse viene catturata! :) (solo un esempio da capire)

+0

finora mi piace l'idea, proverò a implementarla. grazie – dritterweg

+0

era buono .. ho implementato il mio URL di routing come questo nuovo {Controller = "Home", action = "Index", id = ""} Posso ottenere url come: http: // localhost: 53045/Accounts/chjnvd780 . Hai idea del motivo per cui il mio modelstate.isvalid ha ricevuto l'errore? sta mostrando Il valore 'chjnvd780' non è valido per Id.Do hai idea di come risolverlo? – Cherry

6

vorrei suggerire un percorso separato con un vincolo che l'ID o non può corrispondere a uno dei controller o deve corrispondere uno degli ID nel database. Elencarlo prima del percorso predefinito in modo che corrisponda per primo, se le qualifiche sono soddisfatte.

Esempio utilizzando una semplice espressione regolare per un vincolo fisso, anche se probabilmente si desidera creare un vincolo personalizzato derivato da IRouteConstraint che limita i valori in modo dinamico.

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

Si potrebbe desiderare di guardare http://stephenwalther.com/blog/archive/2008/08/07/asp-net-mvc-tip-30-create-custom-route-constraints.aspx per ulteriori idee.