Http get and post method without attribute name

Viewed 5246

I'm using .net Core 2.1 Web API. I add every method [HttpGet("....")] or [HttpPost("....")] like below. But, I don't want to write every method in every controller. I want to write only [HttpGet] or [HttpPost]. How can I achieve this?

Or, if this is not possible, can I do this like [HttpPost("[action]")] with taking automatically actionName?

I'm calling like this: http://localhost:5000/api/University/GetUniversities

This working perfectly

namespace University.API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UniversityController : ControllerBase
    {
        private readonly IUniversityService universityService;

        public UniversityController(IUniversityService universityService)
        {
            this.universityService = universityService;
        }

        [HttpGet("GetUniversities")]
        public async Task<ServiceResult> GetUniversities()
        {
            return await universityService.GetUniversities();
        }

        [HttpGet("GetUniversityStatues")]
        public async Task<ServiceResult> GetUniversityStatues()
        {
            return await universityService.GetUniversityStatues();
        }
    }
}

I tried this but is not working:

namespace University.API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UniversityController : ControllerBase
    {
        private readonly IUniversityService universityService;

        public UniversityController(IUniversityService universityService)
        {
            this.universityService = universityService;
        }

        [HttpGet]
        public async Task<ServiceResult> GetUniversities()
        {
            return await universityService.GetUniversities();
        }

        [HttpGet]
        public async Task<ServiceResult> GetUniversityStatues()
        {
            return await universityService.GetUniversityStatues();
        }
    }
}
4 Answers

Web API like MVC has the convention over configuration, so if you didn't define the endpoint in the attribute, it will work but not as you expect. Generally Get method will be called like this api/[ControllerName] post method the same.

In your case, if you need to name your route the same name of your action you can write this attribute above your controller

[Route("[controller]/[action]")]

You can use just [HttpGet]

    [HttpGet]
    public async Task<ServiceResult> GetUniversities()
    {
        return await universityService.GetUniversities();
    }

And then send a get request to http://localhost:5000/api/University. It will work fine. But your problem is you have more than one parameterless get methods. then it can't identify which get method you need to call.

So if you really want to use two parameterless get methods in same controller you have to decorate it like this,

   [HttpGet("GetUniversities")]
   public async Task<ServiceResult> GetUniversities()
   {
       return await universityService.GetUniversities();
   }

   [HttpGet("GetUniversityStatues")]
   public async Task<ServiceResult> GetUniversityStatues()
   {
       return await universityService.GetUniversityStatues();
   }

Otherwise you have to move the second one to another controller

It's not required to pass the method name with Http Verb. You can use like this also:

        [HttpGet]
        public async Task<ServiceResult> GetUniversities()
        {
            return await universityService.GetUniversities();
        }

But you want to change the method name or route. You can something like this:

        [HttpGet("", Name="Students"]
        public async Task<ServiceResult> GetStudents()
        {
            return await universityService.GetStudents();
        }

You can automate it a little by this

[HttpPost(nameof(GetUniversities))]
Related