Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.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
C# 在IRouter实现ASP.NET核心MVC上获得404_C#_Asp.net Core_Asp.net Mvc Routing_Asp.net Core Mvc - Fatal编程技术网

C# 在IRouter实现ASP.NET核心MVC上获得404

C# 在IRouter实现ASP.NET核心MVC上获得404,c#,asp.net-core,asp.net-mvc-routing,asp.net-core-mvc,C#,Asp.net Core,Asp.net Mvc Routing,Asp.net Core Mvc,我正在尝试实现我自己的动态路由器,我的计划是从我的数据库中提取路由并创建一组动态登录页,我的问题是,在设置context.routedData到我的新路由数据后,我得到了404 我只想在每次找到路由时重定向到我的LandingPageController和索引IActionResult using System.Threading.Tasks; using Microsoft.AspNetCore.Routing; using System.Collections.Generic; using

我正在尝试实现我自己的动态路由器,我的计划是从我的数据库中提取路由并创建一组动态登录页,我的问题是,在设置context.routedData到我的新路由数据后,我得到了404

我只想在每次找到路由时重定向到我的LandingPageController和索引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" };
        }
    }
}
使用System.Threading.Tasks;
使用Microsoft.AspNetCore.Routing;
使用System.Collections.Generic;
使用System.Linq;
命名空间Myproject.Web.Main.Config
{
公共类着陆页面路由器:IRouter
{
公共VirtualPathData GetVirtualPath(VirtualPathContext上下文)
{
返回null;
}
公共任务RouteSync(RouteContext上下文)
{
var requestPath=context.HttpContext.Request.Path.Value;
如果(!string.IsNullOrEmpty(requestPath)&&requestPath[0]=='/'))
{
requestPath=requestPath.Substring(1);
}
var pagefound=GetPages().Any(x=>x==requestPath);
如果(找到页面)
{
//TODO:处理查询字符串
var routeData=新routeData();
路由数据值[“控制器”]=“着陆页面”;
路由数据值[“操作”]=“索引”;
context.RouteData=RouteData;
}
返回Task.FromResult(0);
}
私有IEnumerable GetPages()
{
//TODO:从数据库中提取
返回新列表{“页面url标题”,“另一个动态url”};
}
}
}
我看了这个,但它似乎过时了,上下文中的一些属性在RC2中甚至不存在了


我遗漏了什么?

这似乎不是最好的解决方案,但从我的测试来看,它应该可以满足您的需求


我将默认的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" };
    }
}

这似乎不是最好的解决方案,但从我的测试来看,它应该能满足您的需求


我将默认的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" };
    }
}
基于这个和@sock方法,我传递了route builder,它将同时传递路由器上下文

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));
}
基于这个和@sock方法,我传递了route builder,它将同时传递路由器上下文

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

请停止使用术语MVC6。当/如果旧版MVC的新版本发布时,您只会传播混乱!以前的“ASP.NET 5 MVC6”现在被命名为“ASP.NET Core MVC 1.0”,以明确它不是ASP.NET MVC5的下一个版本,而是从头编写的一个全新框架。另外,正确的标记是
asp.net核心mvc
!看起来是个有趣的场景…你能提供更多的信息吗?因此,如果像
/articles/cavaliers win nba title
这样的请求传入,您希望映射到
/articles/10
url,该url由
articles
控制器处理,并接收文章id
10
,并且在生成链接时,您希望映射以另一种方式发生……对吗?@KiranChalla我希望要在根级别(如mydomain.com/name-of-the-article)和内部配置路由并将这些路由映射到我的登录页控制器,它可以是-article@Tseng是的,我知道这是一个全新的版本,它被重命名为核心MVC,我只是用这个名字,因为以前的问题都是这样写的,所以我的错,我会在下一个问题中试着记住它,谢谢你的提醒,不要再使用MVC6这个词了。当/如果旧版MVC的新版本发布时,您只会传播混乱!以前的“ASP.NET 5 MVC6”现在被命名为“ASP.NET Core MVC 1.0”,以明确它不是ASP.NET MVC5的下一个版本,而是从头编写的一个全新框架。另外,正确的标记是
asp.net核心mvc
!看起来是个有趣的场景…你能提供更多的信息吗?因此,如果像
/articles/cavaliers win nba title
这样的请求传入,您希望映射到
/articles/10
url,该url由
articles
控制器处理,并接收文章id
10
,并且在生成链接时,您希望映射以另一种方式发生……对吗?@KiranChalla我希望要在根级别(如mydomain.com/name-of-the-article)和内部配置路由并将这些路由映射到我的登录页控制器,它可以是-article@Tseng是的,我知道这是一个全新的版本,它被重命名为核心MVC,我只是用这个名字,因为以前的问题都是这样写的,所以我的错,我会在我的下一个问题中试着记住它,谢谢你的提醒,我最终得到了与你提出的类似的方法,你的答案肯定会帮助我指出正确的道路!谢谢,我最终采用了与你所提出的类似的方法,你的答案肯定会帮助我指出正确的道路!很高兴这能起作用,看起来您链接的答案也直接传入了
DefaultHandler
,而不是您的答案中的
IRouteBuilder
——我想知道它们之间的差异意味着什么。也许只是一个告诉不问和偏好的问题?这是我自己在Github上的后期复制,基本上,我实现了IRouterBuiler,因为“routes”(如app.UseMvc中的表达式)实现了IRoutebuilder,我觉得将其作为参数传递更“自然”,但由于缺乏文档,这只是我的观点