【问题标题】:What kind of route would I need to provide vanity urls?我需要什么样的路线来提供虚荣网址?
【发布时间】:2012-11-26 04:11:57
【问题描述】:

我想为我的用户提供一个个性化网址,例如:

www.foo.com/sergio

我需要创建什么样的路线?

假设我有以下控制器和操作,如何将虚 URL 映射到该控制器?

public ActionResult Profile(string username)
{
    var model = LoadProfile(username);
    return View(model);
}

这是我尝试过的以及发生了什么:

选项 A:

每个 url 都被这个路由捕获,这意味着我输入的每个 URL 都将我引导到 Account 控制器,而不仅仅是 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
    );
}

选项 B:

默认路由运行良好,但在尝试访问配置文件 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 }
    );
}

【问题讨论】:

    标签: asp.net-mvc-3 routes vanity-url


    【解决方案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 }
        );
    

    这种方法的缺点是,与现有控制器名称相同的用户名的配置文件视图将不起作用,例如如果有像“asset”、“location”和“AssetController”这样的用户名,则项目中存在“LocationController”,配置文件视图为“资产”、“位置”将不起作用。

    希望这会有所帮助。

    【讨论】:

    • 谢谢你这工作非常好!为了安全起见,我只需要创建一个不允许的虚 URL 的 List<string>。 :)
    • 谢谢,今天这对我有帮助!
    【解决方案2】:

    你试过了吗:

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

    首先要保持“默认”行为。

    【讨论】:

    • 这不能按预期工作,请参阅编辑。 :) 我也悬赏了这个问题。
    猜你喜欢
    • 1970-01-01
    • 2012-10-19
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-14
    • 1970-01-01
    相关资源
    最近更新 更多