Click here to Skip to main content
15,314,714 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I have a simple web api project which I am trying to call using an HttpClient (trying to fetch products from database Table). I get a result of an empty array [] although I have stored data in my Database (SQL Server).

API:

Model:
C#
public partial class Products
{ 
    public int Id { get; set; } 
    public string Name { get; set; }
    public string Category { get; set; }
    public decimal Price { get; set; } 
}

Controller:
C#
public class ProductsController : ApiController
{
    private TestAPIContext db = new TestAPIContext();

    // GET: api/Products
    [ResponseType(typeof(Products))]
    public IQueryable<Products> GetProducts()
    {
        return db.Products;
    }

    // GET: api/Products/5
    [ResponseType(typeof(Products))]
    public async Task<IHttpActionResult> GetProduct(int id)
    {
        Products product = await db.Products.FindAsync(id);
        if (product == null)
        {
            return NotFound();
        }

        return Ok(product);
    }

    // PUT: api/Products/5
    [ResponseType(typeof(void))]
    public async Task<IHttpActionResult> PutProduct(int id, Products product)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        if (id != product.Id)
        {
            return BadRequest();
        }

        db.Entry(product).State = EntityState.Modified;

        try
        {
            await db.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!ProductExists(id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }

        return StatusCode(HttpStatusCode.NoContent);
    }

    // POST: api/Products
    [ResponseType(typeof(Products))]
    public async Task<IHttpActionResult> PostProduct(Products product)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        db.Products.Add(product);
        await db.SaveChangesAsync();

        return CreatedAtRoute("DefaultApi", new { id = product.Id }, product);
    }

    // DELETE: api/Products/5
    [ResponseType(typeof(Products))]
    public async Task<IHttpActionResult> DeleteProduct(int id)
    {
        Products product = await db.Products.FindAsync(id);
        if (product == null)
        {
            return NotFound();
        }

        db.Products.Remove(product);
        await db.SaveChangesAsync();

        return Ok(product);
    }

    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            db.Dispose();
        }
        base.Dispose(disposing);
    }

    private bool ProductExists(int id)
    {
        return db.Products.Count(e => e.Id == id) > 0;
    }
}

HttpClient:
C#
HttpClient client = new HttpClient(); 
client.BaseAddress = new Uri("http://localhost:8090/");

// Add an Accept header for JSON format.
client.DefaultRequestHeaders.Accept.Add(
    new MediaTypeWithQualityHeaderValue("application/json"));

HttpResponseMessage response = client.GetAsync("api/Products").Result;

if (response.IsSuccessStatusCode)
{
    var products = response.Content.ReadAsStringAsync().Result;
    grvProducts.DataSource = products;
}
else
{
    MessageBox.Show("Error Code" + 
        response.StatusCode + " : Message - " + response.ReasonPhrase);
}

Am I doing something wrong?

What I have tried:

I can't figure out what I am doing wrong
Posted
Updated 25-Aug-21 3:18am
v2

1 solution

Quote:
C#
[ResponseType(typeof(Products))]
public IQueryable<Products> GetProducts()
The ResponseType value doesn't match the type you are returning. But since you're returning a concrete type, rather than an IHttpActionResult, that attribute is not required on this action.

Quote:
C#
HttpResponseMessage response = client.GetAsync("api/Products").Result;
...
var products = response.Content.ReadAsStringAsync().Result;
grvProducts.DataSource = products;
Don't use .Result to synchronously get the result of a task. Instead, make your method async, and await the task.

Also, ReadAsStringAsync will return a string, which is not a suitable DataSource. Either use ReadAsAsync<IEnumerable<Products>>(), or parse the JSON string returned from ReadAsStringAsync into a list of Products entities.


Beyond that, if you're not getting any data back, then that means there is no data in your database. You need to check the database to find out why.
   
Comments
Alexander Angelopoulos 26-Aug-21 3:00am
   
Thanks Richard.I agree on the async call part. I will fix this. The thing is that my web api doesn't return data when I test it in Postman either. So I assume there is something wrong with the controler. There are data in my database I double checked it
Richard Deeming 26-Aug-21 3:57am
   
If there was something wrong with the controller, then you'd get an error. If it's returning an empty array, that means it's not finding any data.
Alexander Angelopoulos 26-Aug-21 5:51am
   
Actualy there was a problem with the controler.

I added a route prefix attribute in the controler:

[RoutePrefix("api/Products")]
public class ProductsController : ApiController
private TestApiContext db = new TestApiContext();

and a route attribute in my method:

[Route("")]
public IQueryable<product> GetProducts()
{
return db.Products;
}

and now it fetches all of my data.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900