c# asp.net-mvc routes

c# - Enrutamiento en ASP.NET MVC, mostrando nombre de usuario en URL



asp.net-mvc routes (2)

Estoy tratando de hacer una ruta para poder mostrar el nombre de usuario en la URL de esta manera:

http://localhost1234/john

Aquí está mi 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 } );

Aquí está mi HomeController:

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

En primer lugar, la URL no ha cambiado. Cuando configuro username = "Test" dentro de mi route-config, la URL no cambia.

En segundo lugar, no puedo navegar a mis otros controladores. Si cambio la URL a http://localhost123/Welcome , no pasa nada. Debería redirigirme a una nueva página.

¿Qué estoy haciendo mal aquí?

Si cambio el orden de las rutas, puedo navegar a otras páginas, pero el nombre de usuario no se muestra en la URL.

Busqué en Google y todas las respuestas sobre este tema dicen que debería usar una ruta como la anterior.


Debe clasificar la url para diferentes secciones de su sitio web para que el mecanismo de coincidencia de patrones de url sea fluido. Por ejemplo, en su caso, coloque una categoría ''perfil'' o cualquier otra cosa. Ahora su url de solicitud se verá como http://localhost1234/profile/john y la ruta será

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

Para obtener más información, siga el enlace Enrutamiento en MVC


Por sí solo, su enrutamiento no funcionará porque si la url era .../Product lo que significa que quería navegar al método Index() de ProductController , coincidiría con su primera ruta (y ProductController que "Producto" es el username . Debe agregar una restricción de ruta a sus definiciones de ruta que devuelva true si el username es válido y false si no (en cuyo caso intentará las siguientes rutas para encontrar una coincidencia).

Suponiendo que tiene un UserController con los siguientes métodos

// 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 }

Entonces las definiciones de ruta deben ser

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 la url es .../Bryan , coincidirá con la ruta del User y ejecutará el método Index() en UserController (y el valor del username de username será "Bryan" )

Si la url es .../Stephen/Photos , coincidirá con la ruta UserPhotos y ejecutará el método Photos() en UserController (y el valor del username de username será "Stephen" )

Si la url es .../Product/Details/4 , la restricción de ruta devolverá falso para las primeras 2 definiciones de ruta y ejecutará el método Details() de ProductController

Si la url es .../Peter o .../Peter/Photos y no hay ningún usuario con username = "Peter" , devolverá 404 Not Found

Tenga en cuenta que el código de muestra anterior codifica a los usuarios, pero en realidad llamará a un servicio que devuelve una colección que contiene los nombres de usuario válidos. Para evitar golpear la base de datos en cada solicitud, debe considerar usar MemoryCache para almacenar en caché la colección. El código primero verificará si existe, y si no lo completa, luego verificará si la colección contiene el username . También deberá asegurarse de que la memoria caché se invalide si se agrega un nuevo usuario.