Need help calling Web Api controller methods to retrieve data - c#

I'm new to Web Api (I'm probably missing something very straightforward here) I have a Web Api project with ProductsController.cs that has a property of type List<Product> and I simply want to call the Api in the browser eg localhost/api/products/1 or /api/products/getproduct/1 to retrieve the product response for the specified Id in the url but I cannot get it to retrieve any data. I get a 'not found' error each time. What am I missing to make it find the data and retrieve the response?
I have tried the following:
public IHttpActionResult Get(int id)
{
var product = products.FirstOrDefault(p => p.Id == id);
if (product == null)
{
return NotFound();
}
else
{
return Ok(product);
}
}
And even the following which still returns not found:
public string Get(int id)
{
return "product test";
}

Make sure the the routing is configured properly
WebApiConfig.cs
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
From there you have two options of routing to the action.
Convention-based.
public class ProductsController : ApiController {
//...constructor code removed for brevity
[HttpGet] // Matches GET api/products
public IHttpActionResult GetAllProducts() {
return Ok(products);
}
[HttpGet] // Matches GET api/products/1
public IHttpActionResult GetProduct(int id) {
var product = products.FirstOrDefault(p => p.Id == id);
if (product == null) {
return NotFound();
}
return Ok(product);
}
}
or Attribute routing
[RoutePrefix("api/products")]
public class ProductsController : ApiController {
//...constructor code removed for brevity
[HttpGet]
[Route("")] // Matches GET api/products
public IHttpActionResult GetAllProducts() {
return Ok(products);
}
[HttpGet]
[Route("{id:int}")] // Matches GET api/products/1
public IHttpActionResult GetProduct(int id) {
var product = products.FirstOrDefault(p => p.Id == id);
if (product == null) {
return NotFound();
}
return Ok(product);
}
}

Related

How do i get along with this webapi project error?

Im making a WebApi core project for school and everything seemed fine until i decided to start up the project to test it. When I start it up this error appears https://imgbbb.com/images/2020/01/16/error.png
Here's everything that my project consists of:
And here's the controller code:
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using webapi3.Models;
using webapi3.Models.Repository;
using RouteAttribute = Microsoft.AspNetCore.Components.RouteAttribute;
namespace webapi3.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class EmployeeController : ControllerBase
{
private readonly IDataRepository<Employee> _dataRepository;
public EmployeeController(IDataRepository<Employee> dataRepository)
{
_dataRepository = dataRepository;
}
// GET: api/Employee
[HttpGet]
public IActionResult Get()
{
IEnumerable<Employee> employees = _dataRepository.GetAll();
return Ok(employees);
}
// GET: api/Employee/5
[HttpGet("{id}", Name = "Get")]
public IActionResult Get(long id)
{
Employee employee = _dataRepository.Get(id);
if (employee == null)
{
return NotFound("The Employee record couldn't be found.");
}
return Ok(employee);
}
// POST: api/Employee
[HttpPost]
public IActionResult Post([FromBody] Employee employee)
{
if (employee == null)
{
return BadRequest("Employee is null.");
}
_dataRepository.Add(employee);
return CreatedAtRoute(
"Get",
new { Id = employee.EmployeeId },
employee);
}
// PUT: api/Employee/5
[HttpPut("{id}")]
public IActionResult Put(long id, [FromBody] Employee employee)
{
if (employee == null)
{
return BadRequest("Employee is null.");
}
Employee employeeToUpdate = _dataRepository.Get(id);
if (employeeToUpdate == null)
{
return NotFound("The Employee record couldn't be found.");
}
_dataRepository.Update(employeeToUpdate, employee);
return NoContent();
}
// DELETE: api/Employee/5
[HttpDelete("{id}")]
public IActionResult Delete(long id)
{
Employee employee = _dataRepository.Get(id);
if (employee == null)
{
return NotFound("The Employee record couldn't be found.");
}
_dataRepository.Delete(employee);
return NoContent();
}
}
}
If anyone helps me id be very gratheful! Thanks in advance!
Try changing [controller] to "Employee" in [Route("api/[controller]")]. Check this example from Microsoft 1
Replace [controller] with the name of the controller, which by convention is the controller class name minus the "Controller" suffix. For this sample, the controller class name is TodoItemsController, so the controller name is "TodoItems". ASP.NET Core routing is case insensitive.
Another option, check your Startup.cs file (post it here so we can check if everything is alright). And check this example explaining Attribute Route in .NET Attribute Routing
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}

Getting error while calling WebApi

I am trying to create an API and trying to access it via chrome, expecting it to return the list of Items
public class ProductController : ApiController
{
Product product = new Product();
List<Product> productList = new List<Product>();
[HttpGet]
public HttpResponseMessage GetTheProduct(int id)
{
this.productList.Add(new Product {Id = 111,Name= "sandeep" });
return Request.CreateResponse(HttpStatusCode.OK, this.productList.FirstOrDefault(p => p.Id == 111));
}
}
I have not added route so wanna run it using default route but when i am running it, am getting
No HTTP resource was found that matches the request
URI 'http://localhost:65098/api/GetTheProduct()'.
No type was found that matches the controller named
'GetTheProduct()'.
Suggest me what all things are required to make it work.
If using default routes then configuration may look like this
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
This would mean that routing is using convention-based routing with the following route template "api/{controller}/{id}"
Your controller in its current state is not following the convention. This results in requests not being matched in the route tables which result in the Not Found issues being experienced.
Refactor the controller to follow the convention
public class ProductsController : ApiController {
List<Product> productList = new List<Product>();
public ProductsController() {
this.productList.Add(new Product { Id = 111, Name = "sandeep 1" });
this.productList.Add(new Product { Id = 112, Name = "sandeep 2" });
this.productList.Add(new Product { Id = 113, Name = "sandeep 3" });
}
//Matched GET api/products
[HttpGet]
public IHttpActionResult Get() {
return Ok(productList);
}
//Matched GET api/products/111
[HttpGet]
public IHttpActionResult Get(int id) {
var product = productList.FirstOrDefault(p => p.Id == id));
if(product == null)
return NotFound();
return Ok(product);
}
}
Finally based on the route template configured then the controller expects a request that looks like
http://localhost:65098/api/products/111.
To get a single product that matches the provided id if it exists.
Reference Routing in ASP.NET Web API

ApiController get with id not working

I just started working with ApiController. I'm trying to do an HTTP GET sending an ID, but it is not working.
My ApiController:
[Route("api/Test")]
public class TestController : ApiController
{
private myEntity db = new myEntity();
[HttpGet]
public HttpResponseMessage GetAll()
{
// Get a list of customers
IEnumerable<Customer> customers = db.Customers.ToList();
// Write the list of customers to the response body
HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.OK, customers);
return response;
}
[HttpGet]
public HttpResponseMessage GetById(int id)
{
// Get Customer by id
Customer customer = db.Customers.Where(x => x.Id == id).FirstOrDefault();
HttpResponseMessage response;
if (customer == null)
{
response = Request.CreateResponse(HttpStatusCode.NotFound);
return response;
} else
{
response = Request.CreateResponse(HttpStatusCode.OK, customer);
}
return response;
}
When I run it in the browser, the GetAll method work perfectly. However, when I try GetById:
http://localhost:53198/api/Test/1
It returns:
No HTTP resource was found that matches the request URI http://localhost:53198/api/Test/1
Does anyone know what I am doing wrong?
If using attribute routing you would need to make a few changes to make sure that action routes are distinct to avoid any route conflicts.
[RoutePrefix("api/Test")]
public class TestController : ApiController {
private myEntity db = new myEntity();
//GET api/Test
[HttpGet]
[Route("")]
public IHttpActionResult GetAll() {
// Get a list of customers
var customers = db.Customers.ToList();
// Write the list of customers to the response body
return OK(customers);
}
//GET api/Test/1
[HttpGet]
[Route("{id:int}")]
public IHttpActionResult GetById(int id) {
// Get Customer by id
Customer customer = db.Customers.Where(x => x.Id == id).FirstOrDefault();
if (customer == null) {
return NotFound();
}
return Ok(customer);
}
}
This assumes that attribute routing is enabled
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Attribute routing.
config.MapHttpAttributeRoutes();
// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Reference Attribute Routing in ASP.NET Web API 2
You can do either
http://localhost:53198/api/Test/GetById/1 (as DavidG mentioned)
or
http://localhost:53198/api/Test/1
and changing your code to
[HttpGet]
[Route("{id:int}")]
public HttpResponseMessage GetById(int id)

ASP.Net Web api url is not working

I am new in web api.
i am sure i am doing something wrong for which my action is not getting called.
this is my action
public IEnumerable<Customer> GetCustomersByCountry(string country)
{
return repository.GetAll().Where(
c => string.Equals(c.Country, country, StringComparison.OrdinalIgnoreCase));
}
when i am calling this action this way http://localhost:38762/api/customer/GetCustomersByCountry/Germany
the error is thrown, and error message is
{"Message":"No HTTP resource was found that matches the request URI
'http://localhost:38762/api/customer/GetCustomersByCountry/Germany'.","MessageDetail":"No
action was found on the controller 'Customer' that matches the
request."}
tell me where i made the mistake ? thanks
Web config routes are
config.Routes.MapHttpRoute(
name: "WithActionApi",
routeTemplate: "api/{controller}/{action}/{customerID}"
);
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
EDIT : Full code added
public class CustomerController : ApiController
{
static readonly ICustomerRepository repository = new CustomerRepository();
public IEnumerable<Customer> GetAllCustomers()
{
return repository.GetAll();
}
public Customer GetCustomer(string customerID)
{
Customer customer = repository.Get(customerID);
if (customer == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
return customer;
}
//[ActionName("GetCustomersByCountry")]
public IEnumerable<Customer> GetCustomersByCountry(string country)
{
return repository.GetAll().Where(
c => string.Equals(c.Country, country, StringComparison.OrdinalIgnoreCase));
}
public HttpResponseMessage PostCustomer(Customer customer)
{
customer = repository.Add(customer);
var response = Request.CreateResponse<Customer>(HttpStatusCode.Created, customer);
string uri = Url.Link("DefaultApi", new { customerID = customer.CustomerID });
response.Headers.Location = new Uri(uri);
return response;
}
public void PutProduct(string customerID, Customer customer)
{
customer.CustomerID = customerID;
if (!repository.Update(customer))
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
}
public void DeleteProduct(string customerID)
{
Customer customer = repository.Get(customerID);
if (customer == null)
{
throw new HttpResponseException(HttpStatusCode.NotFound);
}
repository.Remove(customerID);
}
}
just tell me when controller will have multiple get whose parameter name is different then how could i handle the situation.
thanks
Given CustomerController like
public class CustomerController : ApiController {
[HttpGet]
public IEnumerable<Customer> GetCustomersByCountry(string country) {
return repository.GetAll().Where(
c => string.Equals(c.Country, country, StringComparison.OrdinalIgnoreCase));
}
}
a convention-based route can look like this
config.Routes.MapHttpRoute(
name: "CustomerApi",
routeTemplate: "api/customer/{action}/{countryId}",
default: new { controller = "Customer"}
);
which will map http://localhost:38762/api/customer/GetCustomersByCountry/Germany
The problem with your route is that your parameter name in the route template does not match.
Another option could be to use attribute routing
Attribute Routing in ASP.NET Web API 2
[RoutePrefix("api/customer")]
public class CustomerController : ApiController {
//GET api/customer/country/germany
[HttpGet, Route("country/{country}")]
public IEnumerable<Customer> GetCustomersByCountry(string country) {
return repository.GetAll().Where(
c => string.Equals(c.Country, country, StringComparison.OrdinalIgnoreCase));
}
}
with this configuration
public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Web API routes
config.MapHttpAttributeRoutes();
// Other Web API configuration not shown.
}
}
Remove "Get" from the action in the url. Just keep CustomersByCountry instead of GetCustomersByCountry. So the url should be http://localhost:38762/api/customer/CustomersByCountry/Germany.

web api not finding the Get method - 500 error

When i try to make a call to the web api to get a single vendor. It is return a 500 error.
I try to break inside the Get(Guid id) but it never gets inside of it.
I know it is getting to the controller but looks like it can't find the Get(Guid id) function.
Any ideas why? Am I missing something?
web api route
config.Routes.MapHttpRoute(
name: "Module",
routeTemplate: "api/module/{controller}/{id}/{action}",
defaults: new { id = RouteParameter.Optional, action = RouteParameter.Optional }
);
api controller
namespace App.WebUI.Controllers.api.Module
{
public class VendorsController : ApiController
{
private readonly UnitOfWork _repository = new UnitOfWork();
// GET api/Module/vendors
[HttpGet]
public HttpResponseMessage Get()
{
return all;
}
// GET api/Module/vendors/5
[HttpGet]
public HttpResponseMessage Get(Guid id)
{
return single
}
// POST api/Module/vendors
[HttpPost]
public HttpResponseMessage Post(Vendor vendor)
{
insert single
}
[HttpPut]
//PUT api/Module/Vendors
public HttpResponseMessage Put(Vendor vendor)
{
update single
}
}
}
This is what i had to do to make it work.
config.Routes.MapHttpRoute(
name: "Module",
routeTemplate: "api/module/{controller}/{id}/{action}",
defaults: new { id = RouteParameter.Optional, action = "DefaultAction" }
);
Then at the default Action(GET(), GET(id), POST(), PUT(), DELETE()) I added the data annotation: [ActionName("DefaultAction")]

Categories

Resources