2009-02-06 6 views
0

Je suis en train de mettre en œuvre le routage telles que les suivantes:des problèmes avec MVC Routing

messages/535434/Ce-est-un-post-titre

posts/tagged/tags+here 
// Matches {controller}/{action}/{id} - Default 
// Displays all posts with the specified tags 
// uses PostsController : ActionTagged(string tags) 

posts?pageSize=50&pageIndex=4 
// Matches {controller}/{action}/{id} - Default 
// Displays all posts 
// uses PostsController : Index(int? pageSize, int? pageIndex) 

Voici le problème que je veux fais ceci:

posts/39423/this-is-a-post-title-here 
// Typically this is implemented using an action like 'Details' 
// and would normally look like : posts/details/5 

Je n'arrive pas à faire fonctionner correctement le routage. J'ai essayé quelque chose comme ceci:

{controller}/{id}/{description} 

et définir l'action par défaut pour être « Display » qui fonctionne, mais ne me permet pas de naviguer vers d'autres actions nommées comme « Tagged ».

Qu'est-ce qui me manque?

Merci!

Répondre

1

Deux choses:

d'abord, vous devez toujours commander vos itinéraires de spécificité décroissante (par exemple, le cas le plus spécifique en premier lieu, le cas moins spécifique dernière), de sorte que les routes seront « retombent », si l'on ne correspond pas va essayer le prochain.

Nous voulons définir {contrôleur}/{} postID/... (doit être un postid) avant de définir {contrôleur}/{action}/... (peut-être quelque chose d'autre)

Ensuite, nous voulons pouvoir spécifier que si la valeur fournie pour postid ne ressemble pas à un ID de poste, la route devrait échouer et passer à la suivante. Nous pouvons le faire en créant une classe IRouteConstraint:

public class PostIDConstraint : IRouteConstraint 
{ 
    public bool Match(HttpContextBase httpContext, 
    Route route, 
    string parameterName, 
    RouteValueDictionary values, 
    RouteDirection routeDirection) 
    { 
    //if input looks like a post id, return true. 
    //otherwise, false 
    } 
} 

Nous pouvons ajouter à la définition de la route comme ceci:

routes.MapRoute(
    "Default", 
    "{controller}/{postid}/{description}", 
    new { controller = "Posts", action = "Display", id = 0 }, 
    new { postid = new PostIDConstraint() } 
); 
+0

Bonne réponse. Question cependant. Que dois-je faire dans IRouteContraint? Je ne l'ai jamais utilisé, pouvez-vous l'expliquer un peu plus. – Micah

+0

Vous pouvez faire tout ce qui est logique pour vérifier la requête qu'il essaie de valider par rapport à la route. La méthode Match() vous donne la route et les valeurs fournies, vous pouvez écrire if (values ​​["PostID"] = "foo") return true; –

0

Je ne suis pas 100% Je comprends votre question, mais il semble que vous pouvez simplement définir quelques routes différentes.

routes.MapRoute("PostId", "posts/{id}/{title}", 
    new { Controller = "Posts", Action = "DisplayPost", id = 0, title = "" }, 
    new { id = @"\d+" }); 

routes.MapRoute("TaggedPosts", "posts/tagged/{tags}", 
    new { Controller = "Posts", Action = "DisplayTagged", tags = "" }); 

routes.MapRoute("Default", "posts", 
    new { Controller = "Posts", Action = "Index" }); 

Vous pouvez utiliser des expressions régulières pour valider les paramètres comme je l'ai utilisé pour l'identification dans la première voie, ou si vous voulez une meilleure validation faire quelque chose comme Rex M affiché. Les paramètres de chaîne de requête pageSize et pageIndex n'ont pas besoin d'être inclus dans votre itinéraire; ils seront simplement transmis à votre méthode Index tant que les noms de paramètres correspondent.

0

La partie de l'URL qui est la "description" n'est en fait pas utilisée. Par exemple, ce poste est 519222 et je peux toujours y accéder en utilisant l'URL: Having issues with MVC Routing

Questions connexes