Deserialize Json into objects and pass them as arguments to methods

henryvuong

Member
Joined
Sep 8, 2023
Messages
15
Programming Experience
3-5
I am trying to make API calls to Amazon from my C# SDK. In this program, I deserialize a JSON string into C# objects and pass them as arguments into some methods to make API calls. The issue I have is the objects are not the same type with the arguments in the method signature. Below is my code. Pay attention to the "error" comments I make in the Main() method:


C#:
/*
 * Selling Partner API for Listings Items
 *
 * The Selling Partner API for Listings Items (Listings Items API) provides programmatic access to selling partner listings on Amazon. Use this API in collaboration with the Selling Partner API for Product Type Definitions, which you use to retrieve the information about Amazon product types needed to use the Listings Items API.  For more information, see the [Listings Items API Use Case Guide](doc:listings-items-api-v2021-08-01-use-case-guide).
 *
 * OpenAPI spec version: 2021-08-01
 *
 * Generated by: https://github.com/swagger-api/swagger-codegen.git
 */

using System;
using System.IO;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Reflection;
using RestSharp;
using NUnit.Framework;
using SellingPartnerAPI.ListingsItemsAPI.Client;
using SellingPartnerAPI.ListingsItemsAPI.Api;
using SellingPartnerAPI.ListingsItemsAPI.Model;
using Amazon.SellingPartnerAPIAA;
using System.Text.RegularExpressions;
using Newtonsoft.Json;
using static SellingPartnerAPI.ListingsItemsAPI.Test.ListingsApiTests;

namespace SellingPartnerAPI.ListingsItemsAPI.Test
{
    /// <summary>
    ///  Class for testing ListingsApi
    /// </summary>
    /// <remarks>
    /// This file is automatically generated by Swagger Codegen.
    /// Please update the test case below to test the API endpoint.
    /// </remarks>
    [TestFixture]
    public class ListingsApiTests
    {
        private ListingsApi instance;

        /// <summary>
        /// Setup before each unit test
        /// </summary>
        [SetUp]
        public void Init()
        {
            // TODO uncomment below to initialize instance for testing
            //instance = new ListingsApi();
        }

        /// <summary>
        /// Clean up after each unit test
        /// </summary>
        [TearDown]
        public void Cleanup()
        {

        }

        /// <summary>
        /// Test an instance of ListingsApi
        /// </summary>
        [Test]
        public void InstanceTest()
        {
            // TODO uncomment below to test 'IsInstanceOfType' ListingsApi
            //Assert.IsInstanceOfType(typeof(ListingsApi), instance, "instance is a ListingsApi");
        }

        
        /// <summary>
        /// Test DeleteListingsItem
        /// </summary>
        [Test]
        public void DeleteListingsItemTest()
        {
            // TODO uncomment below to test the method and replace null with proper value
            //string sellerId = null;
            //string sku = null;
            //List<string> marketplaceIds = null;
            //string issueLocale = null;
            //var response = instance.DeleteListingsItem(sellerId, sku, marketplaceIds, issueLocale);
            //Assert.IsInstanceOf<ListingsItemSubmissionResponse> (response, "response is ListingsItemSubmissionResponse");
        }
        
        /// <summary>
        /// Test GetListingsItem
        /// </summary>
        [Test]
        public void GetListingsItemTest()
        {
            // TODO uncomment below to test the method and replace null with proper value
            //string sellerId = null;
            //string sku = null;
            //List<string> marketplaceIds = null;
            //string issueLocale = null;
            //List<string> includedData = null;
            //var response = instance.GetListingsItem(sellerId, sku, marketplaceIds, issueLocale, includedData);
            //Assert.IsInstanceOf<Item> (response, "response is Item");
        }
        
        /// <summary>
        /// Test PatchListingsItem
        /// </summary>
        [Test]
        public void PatchListingsItemTest()
        {
            // TODO uncomment below to test the method and replace null with proper value
            //string sellerId = null;
            //string sku = null;
            //List<string> marketplaceIds = null;
            //ListingsItemPatchRequest body = null;
            //string issueLocale = null;
            //var response = instance.PatchListingsItem(sellerId, sku, marketplaceIds, body, issueLocale);
            //Assert.IsInstanceOf<ListingsItemSubmissionResponse> (response, "response is ListingsItemSubmissionResponse");
        }
        
        /// <summary>
        /// Test PutListingsItem
        /// </summary>
        [Test]
        public void PutListingsItemTest()
        {
            // TODO uncomment below to test the method and replace null with proper value
            //string sellerId = null;
            //string sku = null;
            //List<string> marketplaceIds = null;
            //ListingsItemPutRequest body = null;
            //string issueLocale = null;
            //var response = instance.PutListingsItem(sellerId, sku, marketplaceIds, body, issueLocale);
            //Assert.IsInstanceOf<ListingsItemSubmissionResponse> (response, "response is ListingsItemSubmissionResponse");
        }

        //**************** Classes for Listing Item Request body *****************
        public class Root
        {
            public string productType { get; set; }
            public List<Patch> patches { get; set; }
        }
        public class Patch
        {
            public string op { get; set; }
            public string operation_type { get; set; }
            public string path { get; set; }
            public List<Value> value { get; set; }
        }
        public class Value
        {
            public string fulfillment_channel_code { get; set; }
            public int quantity { get; set; }
        }

        //Reference: https://developer-docs.amazon.com/sp-api-blog/docs/automate-your-sp-api-calls-using-the-c-sdk
        public static void Main()
        {
            try
            {
                LWAAuthorizationCredentials lwaAuthorizationCredentials = new LWAAuthorizationCredentials
                {
                    ClientId = "XXXXXXXXXX",
                    ClientSecret = "XXXXXXXXXX",
                    RefreshToken = "XXXXXXXXXX",
                    Endpoint = new Uri("https://api.amazon.com/auth/o2/token")
                };

                ListingsApi listingsApi = new ListingsApi.Builder()
                    .SetLWAAuthorizationCredentials(lwaAuthorizationCredentials)
                    .Build();

                string sellerId = "XXXXXXXXXX";
                List<string> marketplaceIds = new List<string>();
                marketplaceIds.Add("ATVPDKIKX0DER");
                string sku = "XXX-YYY-ZZZ";
                
                //Update qty of a single product
                //Source: https://github.com/amzn/selling-partner-api-docs/issues/2068

                string json = @"
                    {
                        'productType': 'CELLULAR_PHONE',
                        'patches': [
                            {
                                'op': 'replace',
                                'operation_type': 'PARTIAL_UPDATE',
                                'path': '/attributes/fulfillment_availability',
                                'value': [
                                    {
                                        'fulfillment_channel_code': 'DEFAULT',
                                        'quantity': 1
                                    }
                                ]
                            }
                        ]
                    }";

                var patchListing = JsonConvert.DeserializeObject<Root>(json);

                PatchOperation.OpEnum op = (PatchOperation.OpEnum)patchListing.patches[0].op; //Error CS0030: Cannot convert type 'string' to 'PatchOperation.OpEnum'
                string path = patchListing.patches[0].path;
                List<Value> value = patchListing.patches[0].value; //this value is not accepted as an argument in PatchOperation

                PatchOperation patchOperations = new PatchOperation(op, path, value); //Error CS1503 Argument 3: cannot convert from 'Value>' to 'List<object>'
                ListingsItemPatchRequest listingsItemPatchRequest = new ListingsItemPatchRequest(patchListing.productType, patchOperations); //Error CS1503 Argument 2: cannot convert from 'PatchOperation' to 'List<PatchOperation>'
                ListingsItemSubmissionResponse result = listingsApi.PatchListingsItem(sellerId, sku, marketplaceIds, listingsItemPatchRequest);
                Console.WriteLine(result.ToJson());
                Console.ReadLine();
            }
            catch (LWAException e)
            {
                Console.WriteLine("LWA Exception when calling SellersApi#getMarketplaceParticipations");
                Console.WriteLine(e.getErrorCode());
                Console.WriteLine(e.getErrorMessage());
                Console.WriteLine(e.Message);
            }
            catch (ApiException e)
            {
                Console.WriteLine("Exception when calling SellersApi#getMarketplaceParticipations");
                Console.WriteLine(e.Message);
            }
        }
    }
}

Here're the errors (I put these comments in my code above):
Error CS0030: Cannot convert type 'string' to 'PatchOperation.OpEnum'
Error CS1503 Argument 3: cannot convert from 'Value>' to 'List<object>'
Error CS1503 Argument 2: cannot convert from 'PatchOperation' to 'List<PatchOperation>'

The classes I use in the above code can be viewed here:
ListingApi.cs: ListingApi.cs — Codefile
ListingsItemPatchRequest.cs: ListingsItemPatchRequest.cs — Codefile
PatchOperation.cs: PatchOperation.cs — Codefile

So the problem I have is the arguments I pass into the method are not the same type with the method's signature. How can I fixed them?
 
Your original code had data in a JSON string, which you deserialized into your temporary objects, and then tried to feed data from your temporary objects into the Amazon provided class constructors.

All your questions were about how to do the data conversion so that you can do the feeding, as evidenced by the title of your thread: "Deserialize Json into objects and pass them as arguments to methods".

The only thing that post did was completely bypass the JSON string deserialization into your temporary objects. He just created the necessary objects and passed them directly into the Amazon provided classes.

I was trying to answer your question about deserializing and then passing them on as parameters. Looks like a case of an X-Y problem where you kept on asking about problem X, but what you really wanted to solve was problem Y.

My bad was assuming that you had a reason for trying to solve problem X. I saw all the testing related code in the code that you posted and was thinking that in the long run you were going to take advantage of having multiple tests where the only thing that needed to change was the parameters being passed in. You would control those parameters by reading them in from a JSON file, and not need to recompile the tests. As they say about assumptions, it made an ass out of me.
 
@Skydiver
When I posted my question, I wasn't sure what to do so I posted what I thought needed to be done. Now that I realize I do not need the JSON string and deserialize it. Sorry for the confusion, but your help is appreciated. It does help me understand more about subject.
 
Back
Top Bottom