2017-09-29 2 views
2

J'ai un UserController avec les actions suivantes: Register, Login et UserProfile.MVC 5 Route Url ne fonctionne pas

Alors que pour ces actions, je veux de l'URL à:

Register -/utilisateur/Enregistrez-

Login -/Utilisateur/Connexion

UserProfile -/utilisateur/{nom d'utilisateur } (Cette route ne prendra le contrôle que si aucune action n'a été trouvée)

Voilà donc comment mes RouteConfig.cs ressemble:

// Default: 
routes.MapRoute(
    name: "Default", 
    url: "{controller}/{action}/{id}", 
    defaults: new { area = "", controller = "Home", action = "Index", id = UrlParameter.Optional }, 
    namespaces: new[] { "MvcApplication" } 
); 

// User Profile - Default: 
routes.MapRoute(
    name: "UserProfileDefault", 
    url: "User/{username}", 
    defaults: new { area = "", controller = "User", action = "UserProfile" }, 
    namespaces: new[] { "MvcApplication" } 
); 

J'ai besoin que la route pour UserProfile prendra le contrôle que s'il n'y a pas d'action dans le UserController de prendre le contrôle.

Malheureusement, mon code ne fonctionne pas, j'obtiens un 404 pour naviguer vers la route UserProfile, mais toutes les autres actions de UserController fonctionnent.

J'ai également déplacé la route UserProfile vers le haut et ne fonctionne toujours pas, j'ai tout essayé, rien ne semble fonctionner.

+0

qu'est-ce que le paramètre entrant ressemble dans l'action? Pourriez-vous le poster? Et vous allez directement/Utilisateur sans rien utiliser après? Avez-vous essayé User/MyUserName pour voir si cela toucherait l'action? –

Répondre

4

Toutes les 3 URL que vous avez indiqué correspond à la première route (ce qui signifie une URL qui contient entre 0 et 3 segments), et votre 3ème URL (par exemple ../User/OShai) va la méthode OShai() de UserController qui n'existe pas.

Vous devez définir des itinéraires spécifiques dans l'ordre correct (le premier match gagne)

routes.MapRoute(
    name: "Register", 
    url: "/User/Register", 
    defaults: new { area = "", controller = "User", action = "Register" }, 
    namespaces: new[] { "MvcApplication" } 
); 
routes.MapRoute(
    name: "Login", 
    url: "/User/Login", 
    defaults: new { area = "", controller = "User", action = "Login" }, 
    namespaces: new[] { "MvcApplication" } 
); 
// Match any url where the 1st segment is 'User' and the 2nd segment is not 'Register' or 'Login' 
routes.MapRoute(
    name: "Profile", 
    url: "/User/{username}", 
    defaults: new { area = "", controller = "User", action = "UserProfile" }, 
    namespaces: new[] { "MvcApplication" } 
); 
// Default 
routes.MapRoute(
    name: "Default", 
    url: "{controller}/{action}/{id}", 
    defaults: new { area = "", controller = "Home", action = "Index", id = UrlParameter.Optional }, 
    namespaces: new[] { "MvcApplication" } 
); 

Lorsque l'itinéraire Profile correspondra

public ActionResult UserProfile(string username) 

dans UserController

Sinon, vous pourriez supprimer les routes Register et Login et créer une contrainte pour le Profile route pour vérifier au 2ème segment correspond "Enregistrer" ou "Connexion", et si tel est le cas, renvoyer false afin qu'il corresponde alors à la route Default.

public class UserNameConstraint : IRouteConstraint 
{ 
    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     List<string> actions = new List<string>() { "register", "login" }; 
     // Get the username from the url 
     var username = values["username"].ToString().ToLower(); 
     // Check for a match 
     return !actions.Any(x => x.ToLower() == username); 
    } 
} 

puis modifier l'itinéraire Profile à

routes.MapRoute(
    name: "Profile", 
    url: "/User/{username}", 
    defaults: new { area = "", controller = "User", action = "UserProfile" }, 
    constraints: new { username = new UserNameConstraint() } 
    namespaces: new[] { "MvcApplication" } 
);