我需要什么样的途径来提供个性化网址? [英] What kind of route would I need to provide vanity urls?

查看:117
本文介绍了我需要什么样的途径来提供个性化网址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想提供我的用户个性化网址,是这样的:

  www.foo.com/sergio

我需要什么样的途径来创造?

想象一下,我有以下的控制器和动作,我怎么能一个虚荣的URL映射到控制器?

 公众的ActionResult配置文件(用户名字符串)
{
    VAR模型= LoadProfile(用户名);
    返回查看(模型);
}


下面是我试过会发生什么:

选项A:

每个URL陷入了这条路,这意味着每个I型引导我走向账户控制器的URL,而不是仅仅 foo.com/ [用户名] 。没有好。

 公共静态无效的RegisterRoutes(RouteCollection路线)
{
    routes.IgnoreRoute({}资源个.axd / {*} PATHINFO);    routes.MapRoute(
        简介,
        {用户名},
        新{控制器=账户,行动=档案,用户名= UrlParameter.Optional}
    );    routes.MapRoute(
        默认,//路线名称
        {控制器} / {行动} / {ID},// URL带参数
        新{控制器=家,行动=索引,ID = UrlParameter.Optional} //参数默认
    );
}


选项B:

缺省路由的工作很好,但试图访问一个文件时 foo.com/ [用户名] 我得到一个HTTP 404错误。

 公共静态无效的RegisterRoutes(RouteCollection路线)
{
    routes.IgnoreRoute({}资源个.axd / {*} PATHINFO);    routes.MapRoute(
        默认,//路线名称
        {控制器} / {行动} / {ID},// URL带参数
        新{控制器=家,行动=索引,ID = UrlParameter.Optional} //参数默认
    );    routes.MapRoute(
        DentistProfile
        {用户名},
        新{控制器=账户,行动=档案,用户名= UrlParameter.Optional}
    );
}


解决方案

一个解决方案可以使用自定义路由约束的,

 公共类VanityUrlContraint:IRouteConstraint
{
    私人静态只读的String [] =控制器
        Assembly.GetExecutingAssembly()GetTypes(),其中(X => typeof运算(一个IController).IsAssignableFrom(X))。
            。选择(X => x.Name.ToLower()更换(控制器,))。ToArray的()。    公共BOOL匹配(HttpContextBase HttpContext的,路由路径,字符串参数名称,RouteValueDictionary价值,
                      RouteDirection routeDirection)
    {
        返回Controllers.Contains(值[参数名称]的ToString()ToLower将()。)!;
    }
}

和使用它作为

  routes.MapRoute(
        名称:配置文件,
        网址:{用户名},
        默认:新{控制器=账户,行动=简介},
        限制:新{用户名=新VanityUrlContraint()}
    );    routes.MapRoute(
        名称:默认,
        网址:{控制器} / {行动} / {ID}
        默认:新{控制器=家,行动=索引,ID = UrlParameter.Optional}
    );

这种方法的缺点是,对于用户名相同,现有的控制器名纵断面图中是行不通的,就像如果有喜欢的资产,位置,AssetController用户名,LocationController项目的存在,对于个人资料视图资产,位置是行不通的。

希望这有助于。

I'd like to provide my users a vanity url, something like:

www.foo.com/sergio

What kind of route would I need to create?

Imagine I have the following controller and action, how can I map a vanity URL to that controller?

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


Here is what I've tried and what happens:

Option A:

Every url is caught in this route, meaning every URL I type directs me towards the Account controller, instead of only foo.com/[USERNAME]. No good.

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


Option B:

Default routes work well, but when trying to visit a profile foo.com/[USERNAME] I get an HTTP 404 error.

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

解决方案

one solution could be using custom route constraint as,

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

and use it as

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

downside of this approach, profile view for usernames same as existing controller name will not work, like if there are usernames like "asset", "location", and "AssetController", "LocationController" exists in project, profile view for "asset", "location" will not work.

hope this helps.

这篇关于我需要什么样的途径来提供个性化网址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆