ASP.NET路由 - 避免控制器/动作和虚荣/ slug URL之间的冲突

时间:2010-09-28 00:08:48

标签: asp.net-mvc asp.net-mvc-routing

我正在寻找一个很好的解决方案,有一个适用于标准ASP.NET MVC控制器/动作URL的URL方案,例如:

/Home/About --> Controller "Home", Action "About"

和虚荣/ slug网址例如:

/fred/post  --> Controller "Posts", Action "View", User "fred", Post "post"

重要的是,我希望出站网址生成能够正常工作

Html.ActionLink("View", "Posts", new { User="fred", Post="post" }, null }

给/ fred / post - not / Posts / View / fred / post

看起来,我可以让它为入站或出站路由工作,但不能同时工作。或者我可以得到它的工作,但它是凌乱的,容易破碎。有什么方法,提示和技巧可以让这样的东西干净利落地工作?

1 个答案:

答案 0 :(得分:2)

我终于提出了使用路由约束的解决方案,该约束可以检查参数是否与控制器的名称匹配(或不匹配):

public class ControllerConstraint : IRouteConstraint
{
    static List<string> ControllerNames = (from t in System.Reflection.Assembly.GetExecutingAssembly().GetTypes()
                                           where typeof(IController).IsAssignableFrom(t) && t.Name.EndsWith("Controller")
                                           select t.Name.Substring(0, t.Name.Length - 10).ToLower()).ToList();

    bool m_bIsController;
    public ControllerConstraint(bool IsController)
    {

        m_bIsController = IsController;
    }

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (m_bIsController)
            return ControllerNames.Contains(values[parameterName].ToString().ToLower());
        else
            return !ControllerNames.Contains(values[parameterName].ToString().ToLower());
    }  
}

像这样使用:

// eg: /myusername
routes.MapRoute(
    "MemberUrl",
    "{member_urlid}",
    new { controller = "Members", action = "View" },
    new { action="View", member_urlid = new ControllerConstraint(false) }
);

// eg: /myusername/mypagename
routes.MapRoute(
    "ItemUrl",
    "{member_urlid}/{item_urlid}",
    new { controller = "Items", action = "View" },
    new { action="View", member_urlid = new ControllerConstraint(false) }
);

// Normal controller/action routes follow

如果参数与控制器的名称匹配,则约束new ControllerConstraint(false)表示与此路由规则不匹配。传递true以使约束检查参数是否与控制器名称匹配。