Маршрутизация атрибутов ASP.NET Core - префикс языкового стандарта

У меня такой контроллер:

[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 ("Подробности", "Блог", новый {id = 1})
  • @ Url.Action ("Подробности", "Блог", новый {slug = "cat-1", id = 1})
  • @ Url.Action ("Подробности", "Блог", новый {id = 1, locale = "fr"})
  • @ Url.Action ("Подробности", "Блог", новый {slug = "cat-1", id = 1, locale = "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

Я попытался изменить порядок всех атрибутов маршрутизации, но не могу заставить его вернуть желаемый результат, и буду признателен за любую помощь.


person nfplee    schedule 17.06.2020    source источник


Ответы (2)


Следующий пример дает желаемые результаты:

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 для более конкретных маршрутов, поэтому они проверяются в первую очередь. Очевидным недостатком является многословие, но это рабочее решение, основанное на описанных требованиях.

person Kirk Larkin    schedule 23.06.2020

Если вы не против изменить порядок 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
person Yiyi You    schedule 18.06.2020
comment
Спасибо, но слаг должен быть там, где он сейчас находится, поскольку я обновляю приложение с ASP.NET до ядра ASP.NET. Я могу заставить его работать нормально без префикса локали. - person nfplee; 18.06.2020