ASP.NET核心属性路由-语言环境前缀

时间:2020-06-17 20:58:37

标签: c# asp.net-core routes asp.net-core-routing

我有以下控制器:

[Route("blog")]
[Route("{locale:regex(^(de|es|fr)$)}/blog", Order = -1)]
public class BlogController : Controller {
    [HttpGet("{id:int}.htm")]
    [HttpGet("{slug}/{id:int}.htm")]
    public IActionResult Details(string? slug, int id) {
        return View();
    }
}

现在,如果我尝试生成以下URL:

  • @ Url.Action(“ Details”,“ Blog”,新的{id = 1})
  • @ Url.Action(“ Details”, “博客”,新的{slug =“ cat-1”,id = 1})
  • @ Url.Action(“ Details”, “博客”,新的{id = 1,locale =“ fr”})
  • @ Url.Action(“ Details”,“ Blog”, new {slug =“ cat-1”,id = 1,语言环境=“ fr”})

我期望以下几点:

  • /blog/1.htm
  • /blog/cat-1/1.htm
  • /fr/blog/1.htm
  • /fr/blog/cat-1/1.htm

但是这返回:

  • /blog/1.htm
  • /blog/1.htm?slug=cat-1
  • /fr/blog/1.htm
  • /fr/blog/1.htm?slug=cat-1

我尝试更改所有路由属性的顺序,但无法获得所需的结果,因此我们将不胜感激。

2 个答案:

答案 0 :(得分:1)

以下示例给出了预期的结果:

public class BlogController : Controller
{
    [Route("{locale:regex(^(de|es|fr)$)}/blog/{slug}/{id:int}.htm")]
    [Route("{locale:regex(^(de|es|fr)$)}/blog/{id:int}.htm", Order = 1)]
    [Route("blog/{slug}/{id:int}.htm", Order = 2)]
    [Route("blog/{id:int}.htm", Order = 3)]
    public IActionResult Details(string? slug, int id)
    {
        return View();
    }
}

此方法将较早的Order用于更具体的路由,以便首先进行检查。明显的缺点是冗长,但这是根据描述的要求的可行解决方案。

答案 1 :(得分:0)

如果您不介意更改slug的顺序,则可以按以下方式更改控制器:

    [Route("blog")]
    [Route("{locale:regex(^(de|es|fr)$)}/blog", Order = -1)]
    public class BlogController : Controller
    {
        [HttpGet("{id:int}.htm/{slug?}")]
        public IActionResult Details(string? slug, int id)
        {
            return View();
        }
    }

生成以下URL:

@Url.Action("Details", "Blog", new { id = 1 })
@Url.Action("Details", "Blog", new { slug = "cat-1", id = 1 })
@Url.Action("Details", "Blog", new { id = 1, locale = "fr" })
@Url.Action("Details", "Blog", new { slug = "cat-1", id = 1, locale = "fr" })

结果:

/blog/1.htm
/blog/1.htm/cat-1
/fr/blog/1.htm
/fr/blog/1.htm/cat-1