首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有自定义段塞的.NET MVC-4路由

带有自定义段塞的.NET MVC-4路由
EN

Stack Overflow用户
提问于 2013-10-26 21:03:10
回答 1查看 6.8K关注 0票数 11

我正在用ASP.Net MVC 4重写一个网站项目,我发现很难设置正确的路线。url结构不是RESTful或遵循控制器/动作模式-页面具有下面的段塞结构。所有的子弹都保存在数据库中。

代码语言:javascript
复制
/country
/country/carmake
/country/carmake/carmodel
/custom-landing-page-slug
/custom-landing-page-slug/subpage

示例:

代码语言:javascript
复制
/italy
/italy/ferrari
/italy/ferrari/360
/history-of-ferrari
/history-of-ferrari/enzo

由于CountryCar MakeCar Model是不同的模型/实体,所以我希望有一些类似于CountriesController、CarMakesController和CarModelsController的东西,在这里我可以处理不同的逻辑并呈现出相应的视图。此外,我有自定义登陆页,可以有一个或多个斜杠的子弹。

我的第一次尝试是有一个捕获的PagesController,它将查找数据库中的段塞,并根据页面类型调用适当的控制器(例如。CarMakesController),然后执行一些逻辑并呈现视图。然而,我从未成功地“调用”另一个控制器并呈现适当的视图--而且它感觉不对。

有人能指出我的正确方向吗?谢谢!

编辑:为了澄清:我不想重定向--我想根据内容的类型(CountryCarMake等)将请求委托给不同的控制器来处理逻辑和呈现视图。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-10-30 09:12:32

因为您的链接看起来很相似,所以您不能在路由级别将它们分开。但是这里有好消息:您可以编写自定义的路由处理程序,而忽略典型的ASP.NET MVC链接解析。

首先,让我们将RouteHandler附加到默认路由:

代码语言:javascript
复制
routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Default", action = "Index", id = UrlParameter.Optional }
).RouteHandler = new SlugRouteHandler();

这允许您以不同的方式操作您的URL,例如:

代码语言:javascript
复制
public class SlugRouteHandler : MvcRouteHandler
{
    protected override IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        var url = requestContext.HttpContext.Request.Path.TrimStart('/');

        if (!string.IsNullOrEmpty(url))
        {
            PageItem page = RedirectManager.GetPageByFriendlyUrl(url);
            if (page != null)
            {
                FillRequest(page.ControllerName, 
                    page.ActionName ?? "GetStatic", 
                    page.ID.ToString(), 
                    requestContext);
            }
        }

        return base.GetHttpHandler(requestContext);
    }

    private static void FillRequest(string controller, string action, string id, RequestContext requestContext)
    {
        if (requestContext == null)
        {
            throw new ArgumentNullException("requestContext");
        }

        requestContext.RouteData.Values["controller"] = controller;
        requestContext.RouteData.Values["action"] = action;
        requestContext.RouteData.Values["id"] = id;
    }
}

这里需要一些解释。

首先,您的处理程序应该从MvcRouteHandler派生System.Web.Mvc

PageItem表示我的DB-结构,它包含了有关段塞的所有必要信息:

ContentID是内容表的外键。

GetStatic是操作的默认值,在我的情况下很方便。

RedirectManager是一个用于数据库的静态类:

代码语言:javascript
复制
public static class RedirectManager
{
    public static PageItem GetPageByFriendlyUrl(string friendlyUrl)
    {
        PageItem page = null;

        using (var cmd = new SqlCommand())
        {
            cmd.Connection = new SqlConnection(/*YourConnectionString*/);
            cmd.CommandText = "select * from FriendlyUrl where FriendlyUrl = @FriendlyUrl";
            cmd.Parameters.Add("@FriendlyUrl", SqlDbType.NVarChar).Value = friendlyUrl.TrimEnd('/');

            cmd.Connection.Open();
            using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
            {
                if (reader.Read())
                {
                    page = new PageItem
                               {
                                   ID = (int) reader["Id"],
                                   ControllerName = (string) reader["ControllerName"],
                                   ActionName = (string) reader["ActionName"],
                                   FriendlyUrl = (string) reader["FriendlyUrl"],
                               };
                }
            }

            return page;
        }
    }
}

使用此代码库,您可以添加所有限制、异常和奇怪行为。

在我的案子里起作用了。希望这对你有帮助。

票数 25
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19611863

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档