.net 如何处理多条路径相同的路由

axzmvihb  于 2023-02-14  发布在  .NET
关注(0)|答案(1)|浏览(152)

我正在从Ruby on Rails迁移项目到. NET Core,我在路由部分丢失了,因为url中的路径或slug部分命中了多个控制器。

LocationController(string path)
http://www.website.com/asia
http://www.website.com/north-america/usa/florida
Path is everything except website, so: asia, north-america/usa/florida

SchoolController(string slug)
http://www.website.com/st-martin-school
http://www.website.com/rene-claudius-school
Slug is everything except website, so: st-martin-school, rene-claudius-school

PageController(string slug)
http://www.website.com/privacy-policy
http://www.website.com/contact
Slug is everything except website, so: privacy-policy, contact

我知道这个解决方案并不完美,但这是因为SEO的原因,现在我不能改变网址。. NET核心应用程序现在不知道该点击哪个端点。Ruby on Rails上的路由是不同的,它从上到下经过配置的路由,先点击哪个端点,它就被执行。如何在. NET核心中解决这个问题?我读过通配符,但仍然不知道如何使用它。
谢谢你的帮助。

溶液

根据回答,它给了我一个通过自定义约束解决问题的想法。

    • 创建位置约束以捕获以洲名称字符串开头的所有有效位置:**
public class LocationConstraint : IRouteConstraint
    {
        private static readonly string[] continents = { "africa", "asia", "australia", "europe", "north-america", "south-america" };

        public bool Match(HttpContext httpContext, IRouter route, string routeKey, RouteValueDictionary values, RouteDirection routeDirection)
        {
            if (values[routeKey] is null)
            {
                return false;
            }

            string routeValue = values[routeKey].ToString();

            if (continents.Contains(routeValue) || continents.Any(c => routeValue.StartsWith(c + "/", System.StringComparison.CurrentCultureIgnoreCase)))
            {
                return true;
            }

            return false;
        }
    }
    • 捕获LocationController中的所有有效位置:**
[HttpGet("{**path:location}")]
        public async Task<IActionResult> List(string path)
        {
    • 捕获PageController中的所有有效静态路由:**
[HttpGet("latest")]
...

[HttpGet("privacy-policy")]
...
    • 获取SchoolController中的所有学校:**
[HttpGet("{slug}")]
public async Task<IActionResult> Detail(string slug)
        {
ljsrvy3e

ljsrvy3e1#

您可以通过在路由表中Map适当的路由来实现这一点。在ASP.NET核心中,如果控制器是用[ApiController]修饰的,则不允许Map路由。
因此,如果您没有在控制器上使用[ApiController],请遵循我提出的解决方案。
例如,以下是控制器及其内部的操作。

public class LocationController : ControllerBase
{
    [HttpGet]
    public ActionResult Get(string path, string country, string city)
    {
        return new JsonResult(new { Path = path, Country = country, City = city });
    }
}

public class SchoolController : ControllerBase
{
    [HttpGet]
    public ActionResult Get(string slug)
    {
        return new JsonResult(new { Slug = slug });
    }
}

public class PageController : ControllerBase
{
    [HttpGet]
    public ActionResult Get(string slug)
    {
        return new JsonResult(new { PageSlug = slug });
    }
}

以下是所需的路由Map。

app.MapControllerRoute("schoolroute", 
                       "/{slug=*-school}", 
                       new { controller = "School", action = "Get" });
app.MapControllerRoute("privacypolicy", 
                       "/{slug=privacy-policy}", 
                       new { controller = "Page", action = "Get" });
app.MapControllerRoute("contact", 
                       "/{slug=contact}", 
                       new { controller = "Page", action = "Slug" });
app.MapControllerRoute("pathroute", 
                       "/{path}/{country}/{city}", 
                       new 
                       { 
                             controller = "Location", 
                             action = "Get", 
                             country = "", 
                             city = "" 
                       });

上述解决方案中的控制器操作方法签名可能与您的不匹配。我的建议是,如果可能,对您的代码进行适当的更改。否则,请在原始问题中分享相关代码并解释您面临的问题。

相关问题