我想为我的用户提供虚荣网址,例如:
www.foo.com/sergio
我需要创建什么样的路线?
想象一下,我有以下控制器和操作,如何将虚荣URL映射到该控制器?
public ActionResult Profile(string username)
{
var model = LoadProfile(username);
return View(model);
}
以下是我尝试过的以及会发生什么:
每个网址都会在此路由中被捕获,这意味着我输入的每个网址都会将我引导至帐户控制器,而不仅仅是foo.com/[USERNAME]
。不好。
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Profile",
"{username}",
new { controller = "Account", action = "Profile", username = UrlParameter.Optional }
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
}
默认路由效果很好,但在尝试访问配置文件foo.com/[USERNAME]
时出现HTTP 404错误。
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
);
routes.MapRoute(
"DentistProfile",
"{username}",
new { controller = "Account", action = "Profile", username = UrlParameter.Optional }
);
}
答案 0 :(得分:1)
一个解决方案可能是使用自定义路由约束,
public class VanityUrlContraint : IRouteConstraint
{
private static readonly string[] Controllers =
Assembly.GetExecutingAssembly().GetTypes().Where(x => typeof(IController).IsAssignableFrom(x))
.Select(x => x.Name.ToLower().Replace("controller", "")).ToArray();
public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
return !Controllers.Contains(values[parameterName].ToString().ToLower());
}
}
并将其用作
routes.MapRoute(
name: "Profile",
url: "{username}",
defaults: new {controller = "Account", action = "Profile"},
constraints: new { username = new VanityUrlContraint() }
);
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
);
这种方法的缺点是,与现有控制器名称相同的用户名的配置文件视图将不起作用,例如,如果有“资产”,“位置”和“AssetController”等用户名,“LocationController”存在于项目,配置文件视图中“资产”,“位置”将无效。
希望这会有所帮助。
答案 1 :(得分:0)
你试过了吗?
routes.MapRoute(
"YourRouteName",
"{username}",
new {controller="YourController", action="Profile", username=UrlParameter.Optional}
);
这应该陷入www.foo.com/{username}。请记住,路线会按照您添加的顺序进行检查,因此您可以添加
routes.MapRoute(
"default",
"{controller}/{action}/{input}",
new {controller="controller", action="action", input=UrlParameter.Optional}
);
首先保持"默认"行为。