2016-05-21 2 views
4

Im пытается сделать маршрут таким образом я могу показать имя пользователя в URL, как это:маршрутизации в ASP.NET MVC, показывая имя пользователя в URL

http://localhost1234/john

Вот мой 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 } 
      ); 

Вот мой HomeController:

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

Прежде всего, URL не изменяется. Когда я устанавливаю username = "Test" внутри моего маршрута-config, URL-адрес не изменяется.

Во-вторых, я не могу перейти к другим контроллерам. Если я изменю URL-адрес на http://localhost123/Welcome, ничего не произойдет. Он должен перенаправить меня на новую страницу.

Что я здесь делаю неправильно?

Если я изменю порядок маршрутов, я могу перейти на другие страницы, но имя пользователя не отображается в URL-адресе.

У меня есть googled, и все ответы на эту тему говорят, что я должен использовать маршрут, подобный выше.

+0

Возможный дубликат [Как изменить маршрут к имени пользователя после входа?] (Http://stackoverflow.com/questions/36996021/how-to-change-route-to-username-after-logged-in) – NightOwl888

ответ

7

по себе, вашей маршрутизации не будет работать, потому что, если 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. Вам также необходимо убедиться, что кеш был недействительным, если новый пользователь был добавлен.

0

Вам необходимо классифицировать URL-адрес для разных разделов вашего сайта, чтобы механизм соответствия шаблонов URL-адресов шел гладко. Например, в вашем случае укажите категорию «профиль» или что-нибудь другое. Теперь ваш запрос URL выглядеть http://localhost1234/profile/john и маршрут будет

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

Для получения дополнительной информации перейдите по ссылке Routing in MVC

+0

И если я не хочу классифицировать? Посмотрите на facebook. Когда вы посещаете свой профиль, URL-адрес: http: // facebook/yourusername – Bryan

+0

@Bryan. Фактически в приведенном выше примере я сохраняю это для других статических страниц, таких как aboutus, constactus. Вы можете сделать это, удалив Profile/в маршруте в качестве URL: «{username}». В этом случае любой запрос url в форме domain/abc будет искать одно и то же действие для имени пользователя = "abc" –

Смежные вопросы