c# Routage dans ASP.NET MVC, indiquant le nom d'utilisateur dans l'URL




asp.net-mvc routes (2)

Vous devez classer l'URL pour différentes sections de votre site Web afin que le mécanisme de correspondance de modèle d'URL se déroule sans heurts. Par exemple, dans votre cas, mettez une catégorie "profil" ou autre chose. Maintenant, votre URL de requête ressemble à http://localhost1234/profile/john et route sera

 routes.MapRoute(
                name: "users", // Route name
                url: "Profile/{username}", // URL with parameters
                defaults: new { controller = "Home", action = "Index" } // Parameter defaults
            );

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

Pour plus d'informations, suivez le lien Routing in MVC

J'essaie de créer un itinéraire pour pouvoir afficher le nom d'utilisateur dans l'URL suivante:

http://localhost1234/john

Voici mon routeconfig:

 routes.MapRoute(
                name: "users", // Route name
                url: "{username}", // URL with parameters
                defaults: new { controller = "Home", action = "Index", username = "" } // Parameter defaults
            );

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

Voici mon HomeController:

 public ActionResult Index(string username = "Test")
 {
   return View();
  }

Tout d'abord, l'URL n'est pas modifiée. Lorsque je définis username = "Test" dans mon route-config, l'URL n'est pas modifiée.

Deuxièmement, je ne peux pas accéder à mes autres contrôleurs. Si je modifie l'URL en http://localhost123/Welcome , rien ne se passe. Cela devrait me rediriger vers une nouvelle page.

Qu'est-ce que je fais mal ici?

Si je change l'ordre des itinéraires, je peux naviguer vers d'autres pages, mais le nom d'utilisateur n'est pas affiché dans l'URL.

J'ai fait des recherches sur Google et toutes les réponses à ce sujet indiquent que je devrais utiliser un itinéraire comme celui ci-dessus.


En soi, votre routage ne fonctionnera pas, car si l'URL était .../Product ce qui signifie que vous souhaitiez accéder à la méthode Index() de ProductController , elle correspondrait à votre premier itinéraire (et supposons que "Product" est le username . Vous devez ajouter une contrainte de route à vos définitions de roue qui renvoie true si le username est valide et false sinon (dans ce cas, il essaiera les routes suivantes pour trouver une correspondance).

En supposant que vous ayez un UserController avec les méthodes suivantes

// match http://..../Bryan
public ActionResult Index(string username)
{
    // displays the home page for a user
}

// match http://..../Bryan/Photos
public ActionResult Photos(string username)
{
    // displays a users photos
}

Ensuite, vous devez définir les itinéraires

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
        routes.MapRoute(
            name: "User",
            url: "{username}",
            defaults: new { controller = "User", action = "Index" },
            constraints: new { username = new UserNameConstraint() }
        );
        routes.MapRoute(
            name: "UserPhotos",
            url: "{username}/Photos",
            defaults: new { controller = "User", action = "Photos" },
            constraints: new { username = new UserNameConstraint() }
        );
        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Test", action = "Index", id = UrlParameter.Optional }
        );
    }

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

Si l'URL est .../Bryan , il correspondra à la route User et vous exécuterez la méthode Index() dans UserController (et la valeur du username d' username sera "Bryan" )

Si l'URL est .../Stephen/Photos , elle correspond à la route UserPhotos et vous exécuterez la méthode Photos() dans UserController (et la valeur du username d' username sera "Stephen" ).

Si l'URL est .../Product/Details/4 , la contrainte de route renverra false pour les 2 premières définitions de route et vous exécuterez la méthode Details() de ProductController

Si l'URL est .../Peter ou .../Peter/Photos et qu'il n'y a pas d'utilisateur avec username = "Peter" il retournera 404 Not Found

Notez que l'exemple de code ci-dessus code en dur les utilisateurs, mais en réalité, vous appellerez un service qui renvoie une collection contenant les noms d'utilisateur valides. Pour éviter de toucher la base de données à chaque demande, vous devez envisager d'utiliser MemoryCache pour mettre en cache la collection. Le code vérifierait d'abord s'il existe, et s'il ne le remplit pas, vérifiez si la collection contient le username . Vous devez également vous assurer que le cache est invalidé si un nouvel utilisateur est ajouté.





routes