Атрибуты ASP.NET Маршруты и маршруты по умолчанию могут работать вместе? - PullRequest
0 голосов
/ 04 июля 2018

У меня есть проект, написанный на NET Core 2.1, в котором у меня есть куча контроллеров / действий с маршрутами атрибутов на них. Что-то вроде:

[Route("~/test")]
public class ProductsController : Controller
{
    [HttpGet("{id:int}")]
    public IActionResult ById(int id)
    {
        ...
    }
}

А при запуске я просто по умолчанию:

app.UseMvc(routeBuilder =>
{
    routeBuilder.MapRoute(
        name: "default",
        template: "{controller=Home}/{action=Index}/{id?}");
});

Итак, приложение разрешает /test/42, как и ожидалось, но невозможно /products/byid?id=42 работать ... Если я просто закомментирую атрибуты с контроллера, будет использоваться маршрут по умолчанию.

Есть ли способ заставить их работать вместе?

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

Короче: измените его на [Route("/products")] и попробуйте снова.

Подробно:

Если у вас есть атрибут RouteAttribute, примененный к контроллеру или методу действия, то этот метод контролера / действия будет отвечать только на указанный маршрут. В приведенном вами конкретном примере он будет выполняться только при переходе к /~test/65.

Если вы хотите, чтобы методы контроллера / действия работали с именами по умолчанию, попробуйте использовать флажки [controller] и [action] следующим образом:

[Route("[controller]")]
public class ProductsController : Controller
{
    [HttpGet("[action]/{id:int}")] // /Products/ById/5
    public IActionResult ById(int id)
    {
        ...
    }
}

Маршрут по умолчанию в ASP.NET Core - это маршрут, к которому MVC обратится, если ни один из контроллеров не достигнет указанного вами маршрута. В этом случае /Products/ById/5 также сработал бы.

По умолчанию он сопоставляется с контроллером Home и методом действия Index, который является домашней страницей по умолчанию. Если маршрут просто /, то это действие будет выполнено.

Вы также можете сделать это, чтобы просто указать нужный вам маршрут

[Route("/api/products")]
public class ProductsController : Controller
{
    [HttpGet("by-id/{id:int}")] // /api/products/by-id/5
    public IActionResult ById(int id)
    {
        ...
    }
}

Вы также можете попробовать предположение, которое попробовал Джо, так как это тоже метод. Но, в конце концов, вы можете точно настроить маршруты и иметь несколько маршрутов на одном контроллере или действии, если хотите Попробуйте сами поэкспериментировать, но за дополнительной информацией обращайтесь к документации.

Скорее всего, вы не хотите изменять маршрут по умолчанию и настроить свой RouteAttribute по своему вкусу. Прочитайте о атрибутах маршрутизации и маршрутизации к действиям контроллера с помощью app.UseMvc () в предоставленных мною ссылках.

0 голосов
/ 04 июля 2018

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

Если вы хотите использовать атрибут route / products, вы можете изменить его:

[Route("~/products")]
public class ProductsController : Controller
{
    [HttpGet("{id:int}")]
    public IActionResult ById(int id)
    {
        ...
    }
}

но вы не можете использовать оба типа маршрутов для одного и того же контроллера / действия

Единственный обходной путь, о котором я знаю, это то, что вы можете создать другой контроллер, который наследуется от контроллера с помощью атрибутов маршрутов (сделать методы действия виртуальными). Затем вы можете пропустить атрибуты маршрутов с новым субклассифицированным контроллером, и вы можете направить к нему обычными маршрутами и просто вызвать методы действия базового класса.

Пример:

namespace MyNamespace
{
    public class ProductsController : Controller
    {
        [HttpGet("{id:int}")]
        public virtual IActionResult ById(int id)
        {
            ...
        }
    }
}

namespace MyOtherNamespace
{

    public class ProductsController : MyNamespace.ProductsController
    {

        public override IActionResult ById(int id)
        {
            base.ById(id);
        }
    }
}

Теперь вы можете маршрутизировать к ProductsController, используя обычные маршруты, в то время как базовый контроллер использует атрибуты маршрутов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...