Niknak
Niknak

Reputation: 593

Can not fetch data from Rest API - HTTP ERROR 500 - C#

I want to fetch data with customerId and orderId like so:

[HttpGet("customers/{id}/orders/{orderId}")]

But when I change the customerId through URL I get another orderId which does not correspond to the current customer. I want the customerId and orderId to be correct and not fetch order from another customer.

Also, this router:

[HttpGet("customers/{id}/orders")]

This fetches all of the orders from all the customers. I only want the customerId which is given to bring all the specific orders for given customerId.

I'm still trying to grasp around this logic of programming and still new to this. Sorry if this seems silly, but I have tried searching for solutions with no luck for a looooong time. Really appreciate your guidance and help.

Here is what I have so far:

Models:

Customer.cs:

using System.Collections.Generic;

namespace Project.Models
{
    public class Customer
    {
       public string id { get; set; }
       public string firstName { get; set; }
       public string lastName { get; set; }
       public string dateOfBirth { get; set; }
    }
} 

Order.cs:

using System.Collections.Generic;

namespace Project.Models
{
   public class Order
   {
       public string orderId { get; set; }
       public string product { get; set; }
       public string status { get; set; }
       public double price { get; set; }
   }
}

Repositories:

using System.Collections.Generic;
using System.Linq;
using Project.Models;

namespace Project.Repositories
{
   public class OrderRepository
   {

       private static Dictionary<int, Order> ORDERS
                                = new Dictionary<int, Order>();

       static OrderRepository()
       {
           ORDERS.Add(1, new Order
           {
               orderId= "124",
               product= "Shirts",
               status= "On it's way",
               price= 100.20,
           });

           ORDERS.Add(1, new Order
           {
               orderId= "122",
               product= "Pants",
               status= "Not ready",
               price= 300.30,
           });

           ORDERS.Add(2, new Order
           {
               orderId= "143",
               product= "Deadpool",
               status= "On it's way",
               price= 6.20,
           });

           ORDERS.Add(2, new Order
           {
               orderId= "156",
               product= "Socks",
               status= "Not ready",
               price= 3.30,
           });
     }

     public static Order GetByOrderid(int id)
     {
        if (ORDERS==null || ORDERS.Count<1)
          return new Order();
        return ORDERS[id];
     }

     public static List<Order> GetAllOrders()
     {
        if (ORDERS==null || ORDERS.Count<1)
          return new List<Order>();
        return ORDERS.Values.ToList();
     }
}

Controllers:

OrderController.cs:

using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Mvc;
using Project.Models;
using Project.Repositories;

namespace Project.Controllers
{
   public class OrderController : Controller
   {
      [HttpGet("customers/{id}/orders/{orderId}")]
      public Order FindOneOrder(int id)
      {   
          return OrderRepository.GetByOrderid(id);
      }

      [HttpGet("customers/{id}/orders")]
      public List<Order> GetCustomerOrders()
      {
          return OrderRepository.GetAllOrders();
      }
    }
 }

Upvotes: 0

Views: 189

Answers (1)

gunr2171
gunr2171

Reputation: 17520

Issue 1 - route values

You need to use the parameters in your route as parameters in your action method.

[HttpGet("customers/{customerId}/orders/{orderId}")]
public Order FindOneOrder(int customerId, int orderId) //including orderId
{   
    return OrderRepository.GetByOrderid(customerId, orderId);
}

[HttpGet("customers/{customerId}/orders")]
public List<Order> GetCustomerOrders(int customerId) // using customerId
{
    return OrderRepository.GetAllOrders(customerId);
}

I modified "id" to be customerId, which should be easier to understand and maintain.

You will need to modify your repository methods to accept these new arguments.

Issue 2 - dictionary creation

As jdweng said, you are creating a dictionary entries with the same key. Dictionary entries must have unique values.

ORDERS.Add(1, new Order
{
   orderId= "124",
   product= "Shirts",
   status= "On it's way",
   price= 100.20,
});

ORDERS.Add(2, new Order
{
   orderId= "122",
   product= "Pants",
   status= "Not ready",
   price= 300.30,
});

ORDERS.Add(3, new Order
{
   orderId= "143",
   product= "Deadpool",
   status= "On it's way",
   price= 6.20,
});

ORDERS.Add(4, new Order
{
   orderId= "156",
   product= "Socks",
   status= "Not ready",
   price= 3.30,
});

Notice that the first parameter to these calls are always different.

Issue 3 - Using a dictionary in the first place

I'm going to go off of the assumption that the Key of the dictionary is the customer Id. That's not a good idea. A customer can have multiple orders, but you can't hold that data in a dictionary because you can't reuse that key.

Instead, let's modify the Order object to contain the CustomerId:

public class Order
{
   public string CustomerId { get; set; }
   public string OrderId { get; set; }
   public string Product { get; set; }
   public string Status { get; set; }
   public double Price { get; set; }
}

Properties start with a capital letter

Now in our repository we'll use a List<Order> to hold the orders.

private static List<Order> orders;

static OrderRepository()
{
    orders = new List<Order>();

    orders.Add(new Order
    {
        CustomerId = "1",
        OrderId = "1",
        // other properties
    });

    orders.Add(new Order
    {
        CustomerId = "1",
        OrderId = "2",
        // other properties
    });

    // ...etc
}

And our searching methods:

public static Order GetByOrderid(int customerId, int orderId)
{
    return orders
        .Where(x => x.CustomerId == customerId)
        .Where(x => x.OrderId == orderId)
        .SingleOrDefault();
    // remember that the caller needs to check for null value
}
public static List<Order> GetAllOrders(int customerId)
{
    return orders.Where(x => x.CustomerId == customerId).ToList();
}

Upvotes: 3

Related Questions