0
votes

I am new to .NET Core Web API and i'm trying to create Web API with 3 POST methods.

AddUser UpdateUser DeleteUser

I was able to create a .NET core web api project with AddUser POST method and its working fine but they way I want it be uri is

https://localhost:1234/api/Project/AddUser

https://localhost:1234/api/Project/UpdateUser

https://localhost:1234/api/Project/DeleteUser

When I run the application in default swagger uri shows POST /api/Project i.e. https://localhost:1234/api/Project

I am using .NET core web api 5.0

Here code from my controller

namespace ProjectAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    [ApiKeyAuth]
    public class ProjectController : ControllerBase
    {
        [HttpPost]
        public async Task<ActionResult<Response>> AddUser([FromBody] Request request)
        {            
            var _message = await DoSomething(request);
            Response response = new Response
            {
                Message = _message
            };
            return response;
        }      
    

        private async Task<string> DoSomething(Request request)
        {
            string msg = string.Format("Add user {0} to {2} is successful", request.User, request.FromRole, request.ToRole);
            return msg;
        }
    }
}
4

4 Answers

1
votes

@joshykautz is right, you can add routing to each action

Another way is just to change controller routing and not touching actions:

[Route("api/[controller]/[action]")]
public class ProjectController : ControllerBase
....

but after this, if you need, you can still can assign a very special route for some action, for example

[Route("~/api/Project/AddNewUser")]
public async Task<ActionResult<Response>> AddUser( Request request)

Don't miss "~/". It will work for url

https://localhost:1234/api/Project/AddNewUser
0
votes

I kindly recommend not to use ../adduser ../updateuser ../deleteuser in your routing. It also causes security weakness.

You can build your API as /user and add;

yourrouter.route('/user/:id?')
.get(user.get)
.post(user.post)
.put(user.put)
.delete(user.delete);

for the same /user route.

It means, the client calls the same ./user with a specific request (GET, POST, PUT etc.) and with ID and also other parameters if required.

You can test your API and routing via POSTMAN, by selecting the method when you call the API (e.g. https://yourdomain/api/user/{parameters})

0
votes

Give a routing attribute to each action.

[HttpPost]
[Route("api/[controller]/AddUser")]
public async Task<ActionResult<Response>> AddUser([FromBody] Request request)
{            
    var _message = await DoSomething(request);
    Response response = new Response
    {
        Message = _message
    };
    return response;
}    

And remember to remove the routing attribute that you've defined for the class.

You could also use [Route("api/[controller]/[action]")] since your method is already named AddUser.

[HttpPost]
[Route("api/[controller]/[action]")]
public async Task<ActionResult<Response>> AddUser([FromBody] Request request)
{            
    var _message = await DoSomething(request);
    Response response = new Response
    {
        Message = _message
    };
    return response;
}   

You can read more here on the Microsoft Docs.

0
votes

Adding the [action] token to your controller route will yield your desired route format:

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

However, I would discourage using verbs in your route naming. The HTTP method already sufficiently describes the action taken when calling a given endpoint.

  • POST /api/user creates a new user.

  • GET /api/user gets users.

  • PUT /api/user/{id} updates an existing user.

  • DELETE /api/user/{id} deletes a user.

In a RESTful approach, the route describes the resource that you're interacting with on the server, and the HTTP method used describes the action. Mixing actions/verbs into your routes goes against this mindset.

What I would do in your situation is create a new UserController, which will contain the endpoints for your user resource. Having them in a ProjectController, which to me sounds like something that should handle projects, mixes responsibilities and makes your code difficult to understand.