gpt4 book ai didi

asp.net - 带有自定义 slugs 的 .NET MVC-4 路由

转载 作者:行者123 更新时间:2023-12-02 08:25:10 25 4
gpt4 key购买 nike

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

/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

由于 CountryCar MakeCar Model 是不同的模型/实体,我想要一个类似 CountryController、CarMakesController 和CarModelsController 我可以在其中处理不同的逻辑并从中呈现适当的 View 。此外,我有自定义登录页面,其中可以包含包含一个或多个斜杠的段。

我的第一次尝试是拥有一个包罗万象的 PagesController ,它将在数据库中查找 slug 并根据页面类型调用适当的 Controller (例如 CarMakesController >),然后它将执行一些逻辑并渲染 View 。然而,我从未成功地“调用”另一个 Controller 并呈现适当的 View - 而且感觉不对。

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

编辑:澄清一下:我不想重定向 - 我想将请求委托(delegate)给不同的 Controller 来处理逻辑和呈现 View ,具体取决于内容的类型(CountryCarMake等)。

最佳答案

由于您的链接看起来相似,因此您无法在路由级别将它们分开。但这里有个好消息:您可以编写自定义路由处理程序并忘记典型的 ASP.NET MVC 链接的解析。

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

routes.MapRoute(
"Default",
"{controller}/{action}/{id}",
new { controller = "Default", action = "Index", id = UrlParameter.Optional }
).RouteHandler = new SlugRouteHandler();

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

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 的所有必要信息:

PageItem structure

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

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

它对我的情况有效。希望这对您有所帮助。

关于asp.net - 带有自定义 slugs 的 .NET MVC-4 路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19611863/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com