How to create a class and pass a value of an attribute in the class constructor in C #

2

Hello, I'm doing an integration with the Tray Comerce API and thought about generating a generic class with the list answer . In all listings, the API implements the following return class:

public class Response<T>
{
    [JsonProperty("paging")]
    public ResponsePaging Paging { get; set; }

    [JsonProperty("sort")]
    public Dictionary<string, string> Sort { get; set; }

    [JsonProperty("availableFilters")]
    public List<string> AvailableFilters { get; set; }

    [JsonProperty("appliedFilters")]
    public List<string> AppliedFilters { get; set; }

    [JsonProperty(????)]
    public List<T> List { get; set; }

    public class ResponsePaging
    {
        public int total { get; set; }
        public int page { get; set; }
        public int offset { get; set; }
        public int limit { get; set; }
        public int maxLimit { get; set; }
    }
}

The problem is that for each API route that makes a listing, the result of this listing is set to a different name (ex in% with_column returns Orders , in {web_api}/orders returns Products , etc ...)

How do I pass as a parameter to the class what will be the name of the property that will be assigned to {web_api}/products of property [JsonProperty(????)] ?

    
asked by anonymous 20.06.2018 / 15:34

2 answers

3

I was able to solve my problem based on what @tony said in the comment and also in that fiddle I found . The answer was to generate a% custom% with this particular treatment and a return method that applies this conversion. The solution looks like this:

public class Response<A>
{
    private JsonSerializerSettings settings { get; set; }

    public Response(string listName)
    {
        settings = new JsonSerializerSettings
        {
            ContractResolver = new ResponseContractResolver(listName),
            Formatting = Formatting.Indented
        };
    }

    public JsonResponse<A> deserializeObject(string json)
    {
        return JsonConvert.DeserializeObject<JsonResponse<A>>(json, settings);
    }

    public class ResponseContractResolver : DefaultContractResolver
    {
        private string ListName { get; set; }

        public ResponseContractResolver(string listName) => ListName = listName;

        protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
        {
            IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);
            list.Where(x => x.UnderlyingName == "List").First().PropertyName = ListName;
            return list;
        }
    }

    public class JsonResponse<B>
    {
        [JsonProperty("paging")]
        public ResponsePaging Paging { get; set; }

        [JsonProperty("sort")]
        public Dictionary<string, string> Sort { get; set; }

        [JsonProperty("availableFilters")]
        public List<string> AvailableFilters { get; set; }

        [JsonProperty("appliedFilters")]
        public List<string> AppliedFilters { get; set; }

        [JsonProperty("List")]
        public List<B> List { get; set; }

        public class ResponsePaging
        {
            [JsonProperty("total")]
            public int Total { get; set; }

            [JsonProperty("page")]
            public int Page { get; set; }

            [JsonProperty("Offset")]
            public int Offset { get; set; }

            [JsonProperty("Limit")]
            public int Limit { get; set; }

            [JsonProperty("MaxLimit")]
            public int MaxLimit { get; set; }
        }
    }

}

From this generic class, I just need to handle the return and say what name it will return. So 1 single "smart" class and no gambiarra (not no @ rovann-linhalis) solves the problem of the entire API response and reduces the code drastically, as in the example below:

class Foo 
{
    public int Id { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        // resposta em string json da api (mockup de exemplo)
        string jsonResponse = "{\"fooListTest\":[{\"Id\":1},{\"Id\":2},{\"Id\":4}]}";
        List<Foo> foos = new Response<Foo>("fooListTest").DeserializeObject(jsonResponse);
    }
}
    
20.06.2018 / 16:56
1

The ideal would be an inheritance, like this:

public class Response
{
    [JsonProperty("paging")]
    public ResponsePaging Paging { get; set; }

    [JsonProperty("sort")]
    public Dictionary<string, string> Sort { get; set; }

    [JsonProperty("availableFilters")]
    public List<string> AvailableFilters { get; set; }

    [JsonProperty("appliedFilters")]
    public List<string> AppliedFilters { get; set; }

    public class ResponsePaging
    {
        public int total { get; set; }
        public int page { get; set; }
        public int offset { get; set; }
        public int limit { get; set; }
        public int maxLimit { get; set; }
    }
}

public class ProductsResponse : Response
{
    [JsonProperty("products")]
    public List<Product> List { get; set; }
}

public class OrdersResponse : Response
{
    [JsonProperty("orders")]
    public List<Order> List { get; set; }
}

In this way, when executing the request for Products, a ProductsResponse is expected and for requests, OrdersResponse

    
20.06.2018 / 15:50