Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net 带有自定义段塞的.NET MVC-4路由_Asp.net_.net_Asp.net Mvc_Asp.net Mvc 4 - Fatal编程技术网

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

Asp.net 带有自定义段塞的.NET MVC-4路由,asp.net,.net,asp.net-mvc,asp.net-mvc-4,Asp.net,.net,Asp.net Mvc,Asp.net Mvc 4,我正在用ASP.NETMVC4重写一个网站项目,我发现很难设置正确的路径。url结构不是RESTful或遵循控制器/操作模式-页面具有以下slug结构。所有slug都保存在数据库中 /country /country/carmake /country/carmake/carmodel /custom-landing-page-slug /custom-landing-page-slug/subpage 例如: /italy /italy/ferrari /italy/ferrari/360 /

我正在用ASP.NETMVC4重写一个网站项目,我发现很难设置正确的路径。url结构不是RESTful或遵循控制器/操作模式-页面具有以下slug结构。所有slug都保存在数据库中

/country
/country/carmake
/country/carmake/carmodel
/custom-landing-page-slug
/custom-landing-page-slug/subpage
例如:

/italy
/italy/ferrari
/italy/ferrari/360
/history-of-ferrari
/history-of-ferrari/enzo
由于
国家
汽车制造
汽车模型
是不同的模型/实体,我希望有一个类似Countries控制器、Carmakes控制器和Carmodels控制器的东西,我可以处理不同的逻辑并从中呈现适当的视图。此外,我有自定义的登录页,可以有包含一个或多个斜杠的slug

我的第一次尝试是使用一个catch-all
PagesController
,它将在数据库中查找slug并根据页面类型调用相应的控制器(例如
carmakescocontroller
),然后执行一些逻辑并呈现视图。然而,我从未成功地“调用”另一个控制器并呈现适当的视图,而且它感觉不正确

有人能给我指一下正确的方向吗?谢谢


编辑:澄清:我不想重定向-我想将请求委托给另一个控制器来处理逻辑和呈现视图,具体取决于内容的类型(
Country
CarMake
等)。

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

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

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Default", action = "Index", id = UrlParameter.Optional }
).RouteHandler = new SlugRouteHandler();
这允许您以不同的方式使用URL,例如:

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;
    }
}
这里需要一些解释

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

PageItem
表示我的数据库结构,其中包含有关slug的所有必要信息:

ContentID
是内容表的外键

GetStatic
是操作的默认值,对我来说很方便

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

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;
        }
    }
}
使用此代码库,您可以添加所有限制、异常和奇怪的行为


在我的情况下是有效的。希望这对你有所帮助。

正是我所需要的。谢谢。从MvcRouteHandler继承和实现IRouteHandler之间有区别吗?@autonomatt,这是个好问题。我相信至少在这种情况下没有什么大的区别,因为
Route.RouteHandler
属性是
IRouteHandler
,而
MvcRouteHandler
只是它的一个基本实现。因此,如果不使用它的其他方法,
IRouteHandler
将更加干净。