по себе, вашей маршрутизации не будет работать, потому что, если URL был .../Product
это означает, что вы хотите, чтобы перейти к метод Index()
ProductController
, он будет соответствовать вашему первому маршруту (и предположим, что «Продукт» - это username
. Вам нужно добавить ограничение маршрута к вашим определениям маршрутов, которое возвращает true
, если username
действительно и false
, если нет (в этом случае это попробует чтобы найти матч).
Предполагая, что у вас есть UserController
со следующими методами
// 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
}
Затем вы определения маршрута должны быть
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);
}
}
}
Если URL является .../Bryan
, он будет соответствовать User
маршруту, и вы будете выполнять Index()
в UserController
(и значение username
будет "Bryan"
)
Если URL является .../Stephen/Photos
, он будет соответствовать UserPhotos
маршруту, и вы будете выполнять метод Photos()
в UserController
(и значение username
будет "Stephen"
)
Если URL является .../Product/Details/4
, то маршрут ограничение будет возвращать ложь в течение первых 2-х определений маршрутов, и вы будете выполнять Details()
метод ProductController
Если URL является .../Peter
или .../Peter/Photos
и нет пользователя с username = "Peter"
тогда он будет возвращать 404 Not Found
Обратите внимание, что пример кода выше жестких кодов пользователей, но на самом деле вы вызовете службу, которая возвращает коллекцию, содержащую действительные имена пользователей. Чтобы избежать попадания в базу данных каждого запроса, вы должны использовать MemoryCache
для кэширования коллекции. Сначала код проверяет, существует ли он, и если он не заполняется, проверьте, содержит ли коллекция username
. Вам также необходимо убедиться, что кеш был недействительным, если новый пользователь был добавлен.
Возможный дубликат [Как изменить маршрут к имени пользователя после входа?] (Http://stackoverflow.com/questions/36996021/how-to-change-route-to-username-after-logged-in) – NightOwl888