Search code examples
c#servicestackdto

Service Stack response DTO with specific data inside JSON arrays


I'm modeling my response DTOs for services which returns JSON data like this:

{
    "response":
    {
        "metadataA" : "useless info a",
        "metadataB" : "useless info b",
        "metadataC" : "useless info c",
        ...
        "metadataZ" : "useless info z",
        "results" :
        [
            {
                "resultmetadataA" : "useless info a",
                "resultmetadataB" : "useless info b",
                "resultId": "a",
                "resultName": "A"
            },
            {
                "resultmetadataA" : "useless info a",
                "resultmetadataB" : "useless info b",
                "resultId": "b",
                "resultName": "B"
            }

        ]
    }
}

Obviously, I just want my DTO to have a list of results with ids and names like this:

class Response
{
    public List<Result> Results { get; set; }
}

class Result
{
    public string Id  { get; set; }
    public string Name  { get; set; }
}

Is there some property attribute to tell Service Stack the "path" for id and name values?


Edit 1

I'm trying to use some attributes from ServiceStack.DataAnnotations with no luck. Tried to use CompositeIndex(false, "response", "results") in Results and Alias in Results properties, but Results keep coming null.

Help please!

Edit 2

Also tried [DataContract] in Response and [DataMember(Name = Id/Name)] on properties to parse those data directly, but it doesn't seem to work.


Solution

  • Afterall I've found no way to model simple DTOs for complex responses, thanks for all answers anyway.

    Well, it's really sad my POCO's structure being dependent of the JSON response structure. However, I can abstract the response structure and make all my DTOs deal with it at once.

    Considering a similar JSON structure from my question:

    {
        "response":
        {
            ...,
            "results":
            [
                {
                    "resourceType": "letter" ,
                    "resources": ["a", "b", "c", ...]
                },
                {
                    "resourceType": "number" ,
                    "resources": ["1", "2", "3", ...]
                },
                ...
            ]    
        }
    }
    

    I abstracted the commom response structure:

    enum ResourceKind
    {
        Letter,
        Number
    }
    
    public class BaseResponse
    {
        public ResponseContent Response
        {
            get;
            set;
        }
    }
    
    public class ResponseContent
    {
        public List<ResultContent> Results
        {
            get;
            set;
        }
    }
    
    public class ResultContent
    {
        public ResourceKind Kind
        {
            get;
            set;
        }
    
        public List<string> Resources
        {
            get;
            set;
        }
    }
    

    And finally got a simplified implementation for one (of dozens) specific server response:

    public class SpecificResponse : BaseResponse
    {
        public IEnumerable<SpecificResult> Results
        {
            get
            {
                foreach(ResultContent result in Response.Results)
                {
                    SpecificResult newSpecificResult = new SpecificResult();
                    newSpecificResult.Kind = result.Kind;
                    newSpecificResult.Resources = result.Resources;
                    yield return newCategory;
                }
    
                yield break;
            }
        }
    }
    

    I still looking for something better, but for now that's my solution.