【问题标题】:ASP.NET MVC Custom Route class - Can't get route dataASP.NET MVC 自定义路由类 - 无法获取路由数据
【发布时间】:2013-04-22 10:55:02
【问题描述】:

我正在尝试实现自己的路由类,继承自默认路由。

这是我的自定义路由类的样子:

public class FriendlyRoute : Route
{
    public FriendlyRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
        : base(url, defaults, routeHandler)
    {

    }

    public override RouteData GetRouteData(HttpContextBase httpContext)
    {
        var routeData = base.GetRouteData(httpContext);

        var controllerName = routeData.Values["controller"].ToString();
        var actionName = routeData.Values["action"].ToString();

        routeData.Values["controller"] = fix(controllerName);
        routeData.Values["action"] = fix(actionName);

        return routeData;
    }

    private string fix(string name)
    {
        //Remove dashes: "my-controller" => "mycontroller"
    }
}

我正在做的是接受带有破折号的 url 并将其路由到正确的操作(“my-controller/my-action”到“MyController/MyAction”),但我对此自定义路由还有更多计划。

为了让我的自定义路由类生效,我使用以下路由配置:

routes.Add("Default",
           new FriendlyRoute("{controller}/{action}/{id}",
                             new RouteValueDictionary(new { controller = "Public", action = "Start", id = UrlParameter.Optional }),
                             new MvcRouteHandler()));

这很好用!但我对 url 结构不满意。我想要一些没有控制器名称只有操作名称(例如“/about”、“/contact”)和一些带有控制器名称(例如“/mypage”、“/mypage/invoices”)的 url。我首先使用默认路由类(不是我自己的自定义)并解决此问题:

routes.Add("MyPages",
           new Route("MyPage/{action}",
                     new RouteValueDictionary(new { controller = "MyPage", action = "Summary"}),
                     new MvcRouteHandler()));

routes.Add("Public",
           new Route("{action}/{id}",
                     new RouteValueDictionary(new { controller = "Public", action = "Start", id = UrlParameter.Optional }),
                     new MvcRouteHandler()));

这也可以正常工作,但现在不支持带有破折号的网址。所以我只是将我的自定义路由类交换到路由配置中:

routes.Add("MyPages",
           new FriendlyRoute("MyPage/{action}",
                             new RouteValueDictionary(new { controller = "MyPage", action = "Summary" }),
                             new MvcRouteHandler()));

routes.Add("Public",
           new FriendlyRoute("{action}/{id}",
                             new RouteValueDictionary(new { controller = "Public", action = "Start", id = UrlParameter.Optional }),
                             new MvcRouteHandler()));

现在,当我运行应用程序时,我尝试转到默认页面(“/”),但它崩溃了,因为在 FriendlyRoute.GetRouteData() 中对 base.GetRouteData(httpContext) 的调用返回 null。

我是创建自定义路由类的新手,所以任何关于我做错了什么的提示都将不胜感激。

【问题讨论】:

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


    【解决方案1】:

    添加额外的两个路由后,当根 url 被点击(“/”)时,它将根据路由定义从上到下依次处理,直到匹配。所以现在对于第一条路由"MyPage/{action}",它将调用public abstract RouteData GetRouteData(HttpContextBase httpContext); 方法,该方法又将url 与路由定义匹配并检查约束。它在匹配和约束检查的情况下返回RouteValueDictionary 对象,否则返回null。因此,对于第一个路由定义,由于 url 不匹配,它必然会返回 null。你应该添加一个空检查作为愚蠢的

    if (routeData != null)
    {
        var controllerName = routeData.Values["controller"].ToString();
        var actionName = routeData.Values["action"].ToString();
    
        routeData.Values["controller"] = Fix(controllerName);
        routeData.Values["action"] = Fix(actionName);
    }
    

    相关资源:Route.cs

    希望这会有所帮助。

    【讨论】:

    • 好的,我明白了。调用所有路由定义,直到找到匹配的路由,并且当 url 不匹配时它应该返回 null。你让我朝着正确的方向前进。谢谢! :)
    猜你喜欢
    • 1970-01-01
    • 2011-04-02
    • 2020-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多