Moeez
Moeez

Reputation: 478

GET all data from WEB API using console application

I have created a web-API of products following 1 and 2 tutorial. The 2nd tutorial is the console application in which the web-api is called. Now when I create a single product then it is view able. But when I create more than one products than only the last entry is view able. For better understanding see the below code.

static HttpClient client = new HttpClient();

    static void ShowProduct(Product product)
    {

        Console.WriteLine($"Name: {product.Name}\tPrice: {product.Price}\tCategory: {product.Category}");
    }

    static async Task<Uri> CreateProductAsync(Product product)
    {
        HttpResponseMessage response = await client.PostAsJsonAsync("api/product/", product);
        response.EnsureSuccessStatusCode();

        // return URI of the created resource.
        return response.Headers.Location;
    }

    static async Task<Product> GetProductAsync(string path)
    {
        Product product = null;
        HttpResponseMessage response = await client.GetAsync(path);
        if (response.IsSuccessStatusCode)
        {
            product = await response.Content.ReadAsAsync<Product>();
        }
        return product;
    }
static async Task RunAsync()
    {
        int a;
        decimal price = 0;
        string name = null, category = null;
        char option;
        //string url;
        client.BaseAddress = new Uri("http://localhost:7361/");
        client.DefaultRequestHeaders.Accept.Clear();
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        Uri url = null;

        try
        {
            label:
            Console.Write("1. Create a product\n");
            Console.Write("2. View products\n");
            Console.Write("3. Update a product\n");
            Console.Write("4. Delete a product\n");
            Console.Write("5. Exit\n");

            Console.WriteLine("\nEnter your choice: ");
            a = Convert.ToInt32(Console.ReadLine());


            switch(a)
            {
                case 1:

                    Console.WriteLine("Enter name of the product: ");
                    name = Convert.ToString(Console.ReadLine());

                    Console.WriteLine("\nEnter price of the product: ");
                    price = Convert.ToDecimal(Console.ReadLine());
                    Console.WriteLine("\nEnter category of the product: ");
                    category = Convert.ToString(Console.ReadLine());

                    // Create a new product
                    Product product = new Product { Name = name, Price = price, Category = category };

                    url = await CreateProductAsync(product);
                    Console.WriteLine($"Created at {url}");

                    Console.WriteLine("Want to create more product(s)? (y/n): ");
                    option = Convert.ToChar(Console.ReadLine());

                    if(option == 'y' || option == 'Y')
                    {
                        Console.Clear();
                        goto case 1;
                    }
                    else if(option == 'n' || option == 'N')
                    {
                        Console.Clear();
                        goto label;
                    }

                    break;

                case 2:

                    // Get the product
                    product = await GetProductAsync(url.PathAndQuery);

                    ShowProduct(product);

                    break;
                   //case 3:...
                  //case 4:...
                  //case 5:...
       }

I want to view all the created products. For this i have to create a list of products while creating them. But the problem is that I don't know where to do it?

Update 1

On debugging the code the static async Task<Product> GetProductAsync(string path) the path gets the last product id as 'api/product/2', but I want to be like that 'api/product/'. The path includes the last entered id.

Update 2

For getting all the products I have entered the url in product = await GetProductAsync("http://localhost:7361/api/product");

But now after running the application i am getting the below error.

Cannot deserialize the current JSON object (e.g. {“name”:“value”})

Update 3

By checking the API response in Postman following is the data which i got

[
{
    "Id": 1,
    "Name": "yo-yo",
    "Category": "toys",
    "Price": 45
},
{
    "Id": 2,
    "Name": "mobile",
    "Category": "electronics",
    "Price": 45000
}]

Any help would be highly appreciated

Upvotes: 0

Views: 4824

Answers (1)

Chetan
Chetan

Reputation: 6911

The JSON returned from the API (which returns all the products) represents the collection of objects but in your code you are trying to deserialize it to single product object.

product = await response.Content.ReadAsAsync<Product>();

Following is the change you need to do to make your code working. Create a new method which will call GetAllProducts API and return collection of products as following.

static async Task<List<Product>> GetAllProductsAsync(string path)
{
    List<Product> products = null;
    HttpResponseMessage response = await client.GetAsync(path);
    if (response.IsSuccessStatusCode)
    {
        products = await response.Content.ReadAsAsync<List<Product>>();
    }
    return products;
}

I am suggesting to create new method because you might be using the old method somewhere else. Now, use the new method as following in switch case 2:

case 2:
    // Get all the products
    var products = await GetAllProductsAsync(url.PathAndQuery);

    // Loop thru the products and call ShowProduct method for each product in the list.
    foreach(var product in products)
    {
         ShowProduct(product);
    }

This should help you resolve your issue.

Upvotes: 1

Related Questions