1

I am using Visual Studio 2013...

I am having some problems with Api Controller Method.

I understand the differences between HTTPGET, HTTPPUT, [FromUri] and [FromBody].

I have a simple Method, and I am testing all combination.

When I run

http://localhost:62536/api/Controller/Method/10

I Got HTTP 404 error is this examples

[HttpPut]
public string Method([FromUri] int a)
{
return "";
}

[HttpPut]
public string Method( int a)
{
return "";
}

[HttpGet]
public string Method([FromUri] int a)
{
return "";
}

[HttpGet]
public string Method( int a)
{
return "";
}

Got HTTP 405 error is this examples

 [HttpPut]
         public string Method([FromBody] int a)
         {
         }

NO Error, but parameter a is 0..

 [HttpGet]
         public string Method([FromBody] int a)
         {
             return a.ToString();
         }

In other words.. It does not work using [HttpPut] or using parameter not defined or defined as [FromUri].

It only Works with [HttpGet] and [FromBody], but parameters is null.

My WebApiConfig look like this

 public static void Register(HttpConfiguration config)
        {
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
           
        }

Why it is not working?

Diego
  • 2,238
  • 4
  • 31
  • 68

1 Answers1

1

You have to name your parameter in the controller methods as they are named in the route configuration. So, either name it as id:

[HttpPut]
public string Method(int id)
{
return "";
}

[HttpGet]
public string Method(int id)
{
return "";
}

...or, change it in the route config:

 public static void Register(HttpConfiguration config)
 {
     config.Routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: "api/{controller}/{action}/{a}",
         defaults: new { a = RouteParameter.Optional }
     );

 }

Notice that it is now configured as a instead of id

Update

Here are controller methods that should work for the route configured as above:

// Example URI: http://localhost:62536/api/Controller/PutMethod/10
[HttpPut]
public string PutMethod(int a)
{
return a.ToString();
}

// Example URI: http://localhost:62536/api/Controller/GetMethod/10
[HttpGet]
public string GetMethod(int a)
{
return a.ToString();
}

// Example URI: http://localhost:62536/api/Controller/PutMethod/
[HttpPut]
public string PutMethod()
{
return "(none)";
}

// Example URI: http://localhost:62536/api/Controller/GetMethod/
[HttpGet]
public string GetMethod()
{
return "(none)";
}

Usage of GET, PUT, POST, DELETE HTTP Verbs

In essence, RESTful API design revolves around resources which model a business/application domain, URIs that address them, and four basic operations GET, PUT, POST, DELETE (and sometimes the 5th, PATCH). For example, in a Human Resource application domain we have employees. We could represent a collection of employees as a resource addressed by the URI http://example.com/api/Employees and each single employee in the collection as a resource addressed by the URI http://example.com/api/Employee/id, where the id is the ID of an employee. So, we could have:

If the route is configured like:

 public static void Register(HttpConfiguration config)
 {
     config.Routes.MapHttpRoute(
         name: "DefaultApi",
         routeTemplate: "api/{controller}/{id}",i
         defaults: new { id = RouteParameter.Optional }
     );
 }

The controller for employees could then be:

public class EmployeesController : ApiController
{
    // GET api/Employees
    public IEnumerable<Employee> Get()
    {
        List<Employee> employees = null;
        // Get here the list of employees
        return employees;
    }

    // POST api/Employees
    public int Post(Employee employee)
    {
        // Persist here the new employee and determine its ID (for example, identity in SQL Server)
        return employee.Id;  // Returns the ID of the newly created employee
    }

    // GET api/Employees/5
    public Employee Get(int id)
    {
        Employee employee;
        // Get here the employee with the id
        return employee;
    }

    // PUT api/Employees/5
    public Employee Put(int id, Employee employee)
    {
        var updatedEmployee;
        // Find existing employee with the id, update it with the data passed via employee argument and persist it
        return updatedEmployee;  // It's a good practice to return the updated entity back, especially in the case when updating changes some properties, e.g. summarized values, counts, etc.
    }

    // DELETE api/Employees/5
    // More complicated example showing communicating statuses back to the client regarding successfulness of the operation
    public IHttpAction Delete(int id)
    {
        Employee employee;
        // Find the employee with the id
        if (employee == null)
            return NotFound();  // The employee is not found. Signal 404, i.e. there's no resource at this URI.
        // Delete here the employee from the persistence mechanism
        return Ok();  // The employee is found and deleted. Signal 200 - OK
    }
}

Notice there's no need for attributes [HttpGet], [HttpPut], etc. It just all works by convention.

Of course, it's an oversimplified example just to convey the point.

Hope it helps.

Mislav Zic
  • 318
  • 2
  • 8
  • I replace Method(int a) for Method(int id) it partially Works.. Only using HTTGet... and Method(int) or Method([FromUri] .. When I use [FromBody] is null.. and when using HttpPost gave me error 405... it is correct this results? Thanks – Diego Aug 08 '17 at 19:26
  • 1
    How do you want to send it, through URL or through request body? When it is value type (like int) then by convention a parameter is taken from an URL and there is no need to specify [FromUri].If it's [FromBody] specified then you should sent it in the request body. The easiest way is to pass it through URL. Through request body you have to send it as XML, JSON, etc. – Mislav Zic Aug 08 '17 at 19:43
  • Thanks again!!!.. One last question... When Should I use HttpPost? because it always Works with HttpGet... – Diego Aug 08 '17 at 19:59
  • 1
    Pues, I've updated the answer with a simple explanation of when and how to use various HTTP verbs. Hope you'll find it helpful. :) – Mislav Zic Aug 08 '17 at 22:22