Действие контроллера HttpGet выполняет неправильное действие - PullRequest
2 голосов
/ 06 июня 2019

Я создал новый проект Web API из шаблонов Visual Studio, а затем следовал следующему руководству по добавлению OData в этот проект.https://devblogs.microsoft.com/odata/supercharging-asp-net-core-api-with-odata/

Вызов https://localhost:xxx/api/Assets и https://localhost:xxx/api/Assets/1

возвращает все активы, в то время как последний должен возвращать только 1 актив (где id = 1)

Мой код:

public class AssetsController : ControllerBase
{
    private IAssetService _service;
    private IMapper _mapper;

    public AssetsController (IAssetService _service, IMapper mapper)
    {
        this._service = _service;
        this._mapper = mapper;
    }

    [HttpGet]
    [EnableQuery()]
    public ActionResult<IEnumerable<Asset>> Get()
    {
        return this._service.GetAllAssets().ToList();
    }


    [HttpGet("{id}")]
    [EnableQuery()]
    public Asset Get(int id)
    {
        return _service.GetById(id);
    }
}

Я отладил, чтобы убедиться, что функция Get(int id) никогда не вызывается.

Я попытался определить свой маршрут явно так:

[HttpGet]
[Route("GetById/{id}")]
[EnableQuery()]
public Asset Get(int id)
{
    return _service.GetById(id);
}

РЕДАКТИРОВАТЬ

Маршрутизация определена при запуске:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            /* snip */

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

                routeBuilder.Select().Filter().OrderBy().Expand().Count().MaxTop(10);
                routeBuilder.MapODataServiceRoute("api", "api", GetEdmModel());
            });

        }

Это не имеет значения.

Есть идеи?

Ответы [ 2 ]

1 голос
/ 07 июня 2019

Есть два подхода к решению этого вопроса.

Подход 1: переименуйте параметр id в key

В соответствии с документами OData v4 Web API :

Вот несколько правил для сигнатур методов:

  • Если путь содержит ключ, действие должно иметь параметр с именем key.
  • Если путь содержит ключ в свойстве навигации, действие должно иметь> параметр с именем relatedKey.
  • Запросы POST и PUT принимают параметр типа сущности.
  • Запросы PATCH принимают параметр типа Delta, где T - тип объекта.

У нас должен быть параметр с именем key:

[HttpGet("{id}")]  // actually, this line doesn't matter if you're using OData, but it's better to rename it to `key` too
[EnableQuery()]
public IActionResult Get(int key)
{
    ....
}

Подход 2: переименуйте метод Get в GetAsset

В соответствии с Документами OData v4 Web API :

Когда Web API получает запрос OData, сопоставляет запрос с именем контроллера и именем действия . Отображение основано на методе HTTP и URI. Например, GET / odata / Products (1) сопоставляется с ProductsController.GetProduct.

Мы также можем переименовать метод действия в GetAsset, как показано ниже:

[HttpGet("{id}")]
[EnableQuery()]
public IActionResult GetAsset(int id)
{
    ... 
}
0 голосов
/ 06 июня 2019

это сработало у меня ...

[HttpGet]
public ActionResult<IEnumerable<Asset>> Get()
{
    return this._service.GetAllAssets().ToList();
}


[HttpGet("{id}")]
public Asset Get(int id)
{
    return _service.GetById(id);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...