I am using an api for a shopping cart that has some complex json (very complicated to me) data structured like in my screenshot below. In this scenario in my code I am trying to fix an error which I am going to explain by illustrating the data and how its structured as I am very new to JSON and arrays.
This is from the Visual Studio json reader of the data that belongs to an order placed by a customer. This item at the index of [0] has a customFields which has a value.
When a customer completes a purchase, some items they bought can have custom fields, like the size of a shirt (Large) or (Medium) or (Small) etc... In the JSON these customFields have a value which in this case is the size of the shirt for me to display at the thank you page so the customer knows what size he bought. Essentially I am trying to have the data ready to pass to the thank you page view.
When I am calling for these items in my controller, the code only works if ALL the items that were purchased have a customFields. If the customer buys something like a coffee mug that has NO custom fields, then the application breaks because I guess my code is only accounting for items that actually have customFields.
This is the code that I have so far that only works when ALL items that were purchased have a custom field. This is inside my controller.
public ActionResult Thankyou(string token)
{
int itemsCountAddedToCart = (int)obj["items"].Count();
var items = obj["items"].Select(o =>
new Item
{
name = o["name"].ToString(),
quantity = int.Parse(o["quantity"].ToString()),
price = double.Parse(o["price"].ToString()),
image = o["image"].ToString(),
url = o["url"].ToString(),
//This customFields is what works, but only if all items had custom fields.
customFields = o["customFields"][0]["value"].ToString(),
});
thankYouViewModel.OrderItems = items;
}
//ThankYou View Model that loads hold the data to be able to show in the view.
public class ThankYouViewModel
{
public IEnumerable<Item> OrderItems { get; set; }
}
public class Item
{
public string name { get; set; }
public double price { get; set; }
public int quantity { get; set; }
public string image { get; set; }
public string url { get; set; }
//customFields
public string customFields { get; set; }
}
So that code above works, but breaks when I have items that do not have customFields. This is the error that I get:
System.ArgumentOutOfRangeException: 'Index was out of range. Must be non-negative and less than the size of the collection. Parameter name: index'
So how should my code look where its currently breaking so that it can account for situations where one of the items from the JSON does not have a customFields attribute? I am very stuck and have tried to add some conditional statements but did not work because I am dealing with some complex json I do not understand very well yet.
CodePudding user response:
If you want to forget the possibility of more than one element in the customFields array, and only cast the first element value to a string, then use this:
customFields = (o["customFields"] == null || o["customFields"].Count() == 0)?null:o["customFields"][0]["value"].ToString(),
CodePudding user response:
With customFields = o["customFields"][0]["value"].ToString(),
you directly receive the value from the customFields Array. If there is no Array in your case then there is nothing to get.
I would recommend you to check if your customFields exists:
var item = new Item ();
item.name = o["name"].ToString();
item.quantity = int.Parse(o["quantity"].ToString());
item.price = double.Parse(o["price"].ToString());
item.image = o["image"].ToString();
item.url = o["image"].ToString();
if(o["customFields"] != null)
{
item.customFields = o["customFields"][0]["value"].ToString();
}