我试图实现自己的动态路由器,我的计划是从我的数据库中提取路线并创建一组动态着陆页,我的问题是我在设置上下文后得到404。 RouteData到我的新路线数据。
我只是想在每次找到路线时重定向到我的LandingPageController和Index IActionResult。
using System.Threading.Tasks;
using Microsoft.AspNetCore.Routing;
using System.Collections.Generic;
using System.Linq;
namespace Myproject.Web.Main.Config
{
public class LandingPageRouter : IRouter
{
public VirtualPathData GetVirtualPath(VirtualPathContext context)
{
return null;
}
public Task RouteAsync(RouteContext context)
{
var requestPath = context.HttpContext.Request.Path.Value;
if (!string.IsNullOrEmpty(requestPath) && requestPath[0] == '/')
{
requestPath = requestPath.Substring(1);
}
var pagefound = GetPages().Any(x => x == requestPath);
if (pagefound)
{
//TODO: Handle querystrings
var routeData = new RouteData();
routeData.Values["controller"] = "LandingPage";
routeData.Values["action"] = "Index";
context.RouteData = routeData;
}
return Task.FromResult(0);
}
private IEnumerable<string> GetPages()
{
//TODO: pull from database
return new List<string> { "page-url-title", "another-dynamic-url" };
}
}
}
我查看了这个answer,但似乎过时的情况下,某些属性在RC2中甚至不再存在。
我错过了什么?
答案 0 :(得分:2)
它似乎不是最好的解决方案,但从我的测试来看,它应该适合您的要求。
我将默认MVC IRouter
注入您的LandingPageRouter
。然后,一旦更新了路由数据,只需调用默认路由器并传入上下文:
public class LandingPageRouter : IRouter
{
private readonly IRouter _router;
public LandingPageRouter(IRouter router)
{
_router = router;
}
public VirtualPathData GetVirtualPath(VirtualPathContext context)
{
return null;
}
public Task RouteAsync(RouteContext context)
{
var requestPath = context.HttpContext.Request.Path.Value;
if (!string.IsNullOrEmpty(requestPath) && requestPath[0] == '/')
{
requestPath = requestPath.Substring(1);
}
var pagefound = GetPages().Any(x => x == requestPath);
if (pagefound)
{
//TODO: Handle querystrings
var routeData = new RouteData();
routeData.Values["controller"] = "LandingPage";
routeData.Values["action"] = "Index";
context.RouteData = routeData;
return _router.RouteAsync(context);
}
return Task.FromResult(0);
}
private IEnumerable<string> GetPages()
{
//TODO: pull from database
return new List<string> { "page-url-title", "another-dynamic-url" };
}
}
然后只需在Startup.Configure
中添加路线的位置插入默认路线:
app.UseMvc(routes =>
{
routes.Routes.Add(new LandingPageRouter(routes.DefaultHandler));
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
答案 1 :(得分:0)
基于这个answer和@sock方法,我传递了路由构建器,它将同时传递路由器上下文
public LandingPageRouter(IRouteBuilder routeBuilder)
{
_routeBuilder = routeBuilder;
}
public Task RouteAsync(RouteContext context)
{
var requestPath = context.HttpContext.Request.Path.Value;
if (!string.IsNullOrEmpty(requestPath) && requestPath[0] == '/')
{
requestPath = requestPath.Substring(1);
}
var pagefound = GetPages().SingleOrDefault(x => x.Name == requestPath);
if (pagefound!=null)
{
//TODO: Handle querystrings
var routeData = new RouteData();
routeData.Values["controller"] = "LandingPage";
routeData.Values["action"] = "Index";
routeData.Values["id"] = pagefound.Id;
context.RouteData = routeData;
return _routeBuilder.DefaultHandler.RouteAsync(context);
}
return Task.FromResult(0);
}
startup.cs中的路由配置
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
routes.Routes.Add(new LandingPageRouter(routes));
}