HttpGetAttribute не работает в основных веб-API - PullRequest
0 голосов
/ 14 марта 2020

Хорошо известная ситуация. Мне нужны две конечные точки

GetAll -> API / бренды

GetById -> API / бренды / 1

[ApiController]
[Route("api/[controller]")]
public class BrandsController : ControllerBase
{
    private readonly BrandRepository repository;

    public BrandsController(BrandRepository repository)
    {
        this.repository = repository;
    }

    [HttpGet("{id:int}")]
    public async Task<ActionResult> GetById(int id)
    {
        var brand = await repository.FindAsync(id);
        if (brand == null)
        {
            return NotFound();
        }

        return Ok(brand);
    }

    [HttpGet("")]
    public ActionResult<IEnumerable<Brand>> GetAll()
    {
        var brands = repository.GetAll().ToList(); 

        return Ok(brands);
    }}

Итак, я всегда попадаю в GetAll ( ) Есть идеи? Помогите, пожалуйста:)

Postman request

Это правильное пространство имен?

using Microsoft.AspNetCore.Mvc;

для

[HttpGet]

Startup.cs

namespace BackOffice
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();

            services.AddDbContext<ApplicationDbContext>(
                options => 
                options.UseMySql(Configuration.GetConnectionString("local")));

            services.AddTransient<BrandRepository, BrandRepository>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseHttpsRedirection();
            app.UseRouting();
            app.UseAuthorization();
            app.UseEndpoints(
                endpoints =>
                {
                    endpoints.MapControllers();
                });

            app.UseCors();
        }
    }
}

dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd d ddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd

1 Ответ

0 голосов
/ 15 марта 2020

Измените свой атрибут в действии GetAll просто на [HttpGet], а затем измените атрибут в действии GetById на [HttpGet ("{id}")].

Вы можете использовать ограничение для id, если это необходимо, но в вашем случае я не вижу в этом необходимости. Обычно вы можете использовать ограничения, когда у вас есть несколько действий на одном маршруте, но с разными типами параметров. Например, «api / brands / 1» для получения по целочисленному идентификатору, а затем, возможно, у вас есть другое действие, сопоставленное с «api / brands / gucci», которое будет искать бренд по имени строки. Затем вы можете использовать ограничения {id: int} и {id: string} в шаблоне маршрута, чтобы определить, какое действие вызывать.

Также убедитесь, что вы используете IActionResult при объявлении типов возвращаемых действий. Вы не хотите использовать конкретный тип ActionResult. Примеры кода ниже.

Для действия GetById:

[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id)
{
    var brand = await repository.FindAsync(id);
    if (brand == null)
    {
        return NotFound();
    }

    return Ok(brand);
}

Для вашего действия GetAll:

[HttpGet]
public IActionResult<IEnumerable<Brand>> GetAll()
{
    var brands = repository.GetAll().ToList(); 

    return Ok(brands);
}

Это сообщит промежуточному программному обеспечению маршрутизации, какое действие вызывать. Для действий, которые вы хотите сопоставить с маршрутом базового контроллера (т. Е. «Api / brands»), просто используйте атрибут без перегрузки. Такие как [HttpGet], [HttpPost], [HttpDelete]. Для действий, которые имеют параметр маршрута, вы можете использовать [HttpGet ("{id}")] и так далее, в зависимости от метода HTTP. Не беспокойтесь об определении типа параметра в шаблоне маршрута атрибута. Вы определяете параметр в параметрах вашего действия. Например:

[HttpGet("{id}")]
public async Task<IActionResult> GetById(int id)
{
    // Code here

    return Ok();
}

Если вы хотите сопоставить маршрут с чем-то вроде «api / brands / designer / 2», то вы бы использовали шаблон, такой как [HttpGet ("designer / {id}")] сделать это. Не ставьте "/" перед дизайнерами.

Изменить: Забыл упомянуть, убедитесь, что ваш Startup.cs правильно настроен для маршрутизации Web API. Вы можете прочитать подробности в документах ASP. NET Core 3.1, чтобы узнать, что делают все эти опции. Если вы использовали шаблон Web API, то это, вероятно, хорошо, но стоит дважды проверить, так как неправильно настроенная маршрутизация конечной точки может вызвать проблемы. Убедитесь, что у вас есть следующее в вашем методе Configure в Startup.cs.

app.UseRouting();

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllers();
});

Убедитесь, что app.UseRouting (); вызывается перед app.UseEndpoints ();

...