Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to add custom methods to ASP.NET WebAPI controller?

In ASP.NET MVC WebAPI project by default we have created following controller

 public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        public void Post([FromBody]string value)
        {
        }

        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }
}

But is possible to add here any custom methods so they can support get/post as well?

Thank you!

like image 822
Friend Avatar asked Jul 19 '14 17:07

Friend


People also ask

Can a controller have multiple post methods?

Open your controller class, in our project its ValuesController. cs >> Copy paste below code, these are two sample post methods with a string input and return parameter – you can write your business logic in it. Similarly, you can add any number of POST, GET, PUT, DELETE methods in one controller.


4 Answers

You can use attributes such as the RoutePrefix with the Http type.

[Route("ChangePassword")]
[HttpPost] // There are HttpGet, HttpPost, HttpPut, HttpDelete.
public async Task<IHttpActionResult> ChangePassword(ChangePasswordModel model)
{        
}

The http type will map it back to its correct method in combination with the Route name.

like image 90
Shawn Mclean Avatar answered Oct 17 '22 10:10

Shawn Mclean


I am not sure I follow as you have GET and POST right there in your code, but in any case you have other options:

Option 1

First, you can configure your custom Routes in the App_Start folder in the WebApiConfig.cs file. Here is what I normally use:

    // GET /api/{resource}/{action}
    config.Routes.MapHttpRoute(
        name: "Web API RPC",
        routeTemplate: "{controller}/{action}",
        defaults: new { },
        constraints: new { action = @"[A-Za-z]+", httpMethod = new HttpMethodConstraint("GET") }
        );
    
    // GET|PUT|DELETE /api/{resource}/{id}/{code}
    config.Routes.MapHttpRoute(
        name: "Web API Resource",
        routeTemplate: "{controller}/{id}/{code}",
        defaults: new { code = RouteParameter.Optional },
        constraints: new { id = @"\d+" }
        );

    // GET /api/{resource}
    config.Routes.MapHttpRoute(
        name: "Web API Get All",
        routeTemplate: "{controller}",
        defaults: new { action = "Get" },
        constraints: new { httpMethod = new HttpMethodConstraint("GET") }
        );

    // PUT /api/{resource}
    config.Routes.MapHttpRoute(
        name: "Web API Update",
        routeTemplate: "{controller}",
        defaults: new { action = "Put" },
        constraints: new { httpMethod = new HttpMethodConstraint("PUT") }
        );

    // POST /api/{resource}
    config.Routes.MapHttpRoute(
        name: "Web API Post",
        routeTemplate: "{controller}",
        defaults: new { action = "Post" },
        constraints: new { httpMethod = new HttpMethodConstraint("POST") }
        );

    // POST /api/{resource}/{action}
    config.Routes.MapHttpRoute(
        name: "Web API RPC Post",
        routeTemplate: "{controller}/{action}",
        defaults: new { },
        constraints: new { action = @"[A-Za-z]+", httpMethod = new HttpMethodConstraint("POST") }
        );

I use a combination of RESTful endpoints as well as RPC endpoints. For some purists, this is grounds for a holy war. For me, I use a combination of the two because it is a powerful combination and I can't find any sane reason not to.

Option 2

As the others have pointed out and as I myself am doing more of these days, use attribute routing:

    [HttpGet]
    [GET("SomeController/SomeUrlSegment/{someParameter}")]
    public int SomeUrlSegment(string someParameter)
    {
        //do stuff
    }

I needed a NuGet package for attribute routing to make this work (just search NuGet for "Attribute Routing"), but I think that MVC 5/WebAPI 2 has it natively.

Hope this helps.

like image 29
Matt Cashatt Avatar answered Oct 17 '22 09:10

Matt Cashatt


You could use attribute routing:

[Route("customers/{customerId}/orders")]
public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }

Some documentation to get you started:

http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

like image 33
Iain Avatar answered Oct 17 '22 09:10

Iain


First Put this route to webapiconfig.cs

config.Routes.MapHttpRoute(
            name: "ApiWithAction",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

Now you can add actions to your controllers like this

 [HttpPost]
    public void Upload()
    {
           //Do some thing
    }

I decorated upload action with httppost attribute that means this action accept just only post requests , if you want to actions to be GET , you can remove attribute or just decorate to your suite

like image 20
elia07 Avatar answered Oct 17 '22 09:10

elia07