在 .NET Core 5 中更新 RouteTable
Updating RouteTable in .NET Core 5
我正在尝试为我正在构建的小型 CMS 的内容页面创建自定义路由。我一直使用如下所示的结构,我在其中为数据库中存在的每个内容页创建一个具有唯一标识符的特定路由。这发生在 startup.cs
routes.MapRoute(
page.Id.ToString(), // Unique route name
page.Url.TrimStart('/'), // URL with parameters
new { controller = "Home", action = "GetPage", guid = page.Id } // Parameter defaults
);
这使得我可以在我的控制器中做这样的事情
public ActionResult GetPage()
{
Guid id = Guid.Parse(RouteData.Values["guid"].ToString());
// content page?
ContentPageModel model = pageService.GetPageById(id);
return View("index", model);
}
这在(相对)复杂的树结构的情况下非常方便。我现在正在从头开始构建一些东西,我想再次使用类似的结构。以上在 .NET Core 5 中有效。但是,我正在努力的地方是在保存时更新路由 table。如果页面有 URL 更改,我想更新路由 table。但是,RouteTable
不再存在,我找不到如何从我的控制器或服务更新路由。这就是我过去常做的事情(有点 ;)
var routes = RouteTable.Routes;
// remove old route
var oldRoute = routes[routeItem.RouteName];
routes.Remove(oldRoute);
//add new route for page
routes.MapRoute(
routeItem.RouteName, // Route name
routeItem.Url, // URL with parameters
new { controller = routeItem.Controller, action = routeItem.Action, guid = routeItem.RouteName } // Parameter defaults);
编辑:
所以我使用 MapDynamicControllerRoute
:
解决了这个问题
endpoints.MapDynamicControllerRoute<CmsRouteTransformer>("/{**slug}");
然后你可以这样做:
public class CmsRouteTransformer : DynamicRouteValueTransformer
{
public override async ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
{
string url = string.Join("/", values.Values);
var pageId = await _pageFinder.FindByUrl(url);
if(pageId == null)
{
values["controller"] = "Home";
values["action"] = "NotFound";
}
else
{
values["controller"] = "Home";
values["action"] = "Page";
values["guid"] = pageId;
}
return values;
}
}
pageFinder
只是一个具有 slug/id 映射的服务,该映射得到更新 onSave
。
我正在尝试为我正在构建的小型 CMS 的内容页面创建自定义路由。我一直使用如下所示的结构,我在其中为数据库中存在的每个内容页创建一个具有唯一标识符的特定路由。这发生在 startup.cs
routes.MapRoute(
page.Id.ToString(), // Unique route name
page.Url.TrimStart('/'), // URL with parameters
new { controller = "Home", action = "GetPage", guid = page.Id } // Parameter defaults
);
这使得我可以在我的控制器中做这样的事情
public ActionResult GetPage()
{
Guid id = Guid.Parse(RouteData.Values["guid"].ToString());
// content page?
ContentPageModel model = pageService.GetPageById(id);
return View("index", model);
}
这在(相对)复杂的树结构的情况下非常方便。我现在正在从头开始构建一些东西,我想再次使用类似的结构。以上在 .NET Core 5 中有效。但是,我正在努力的地方是在保存时更新路由 table。如果页面有 URL 更改,我想更新路由 table。但是,RouteTable
不再存在,我找不到如何从我的控制器或服务更新路由。这就是我过去常做的事情(有点 ;)
var routes = RouteTable.Routes;
// remove old route
var oldRoute = routes[routeItem.RouteName];
routes.Remove(oldRoute);
//add new route for page
routes.MapRoute(
routeItem.RouteName, // Route name
routeItem.Url, // URL with parameters
new { controller = routeItem.Controller, action = routeItem.Action, guid = routeItem.RouteName } // Parameter defaults);
编辑:
所以我使用 MapDynamicControllerRoute
:
endpoints.MapDynamicControllerRoute<CmsRouteTransformer>("/{**slug}");
然后你可以这样做:
public class CmsRouteTransformer : DynamicRouteValueTransformer
{
public override async ValueTask<RouteValueDictionary> TransformAsync(HttpContext httpContext, RouteValueDictionary values)
{
string url = string.Join("/", values.Values);
var pageId = await _pageFinder.FindByUrl(url);
if(pageId == null)
{
values["controller"] = "Home";
values["action"] = "NotFound";
}
else
{
values["controller"] = "Home";
values["action"] = "Page";
values["guid"] = pageId;
}
return values;
}
}
pageFinder
只是一个具有 slug/id 映射的服务,该映射得到更新 onSave
。