none
Map two Lists and return them as JSON RRS feed

  • Question

  • I'm trying to build a RESTFul API and I want to map Two different Lists together and return them as JSON Objects. The thing is Users have multiple Address and Addresses are stored in a Different file and User details are stored in a different file. 

    PersonDataAccess.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using DataAccess.BO;
    
    namespace DataAccess
    {
        public class PersonDataAccess
        {
            #region Data
            public static readonly List<User> Data = new List<User>
            {
                new User
                {
                    Id = 8,
                    GivenName = "Trinh",
                    FamilyName = "Montejano",
                    BossId = 3,
                    Title = "Tech Manager",
                    Gender = Gender.Unspecified,
                    DateOfBirth = DateTime.Parse("1966-09-27")
                },
                new User
                {
                    Id = 1,
                    GivenName = "Winfred",
                    FamilyName = "Fetzer",
                    BossId = null,
                    Title = "CEO",
                    Gender = Gender.Unspecified,
                    DateOfBirth = DateTime.Parse("1927-01-29")
                },
                new User
                {
                    Id = 2,
                    GivenName = "Erich",
                    FamilyName = "Dandrea",
                    BossId = 1,
                    Title = "VP of Marketing",
                    Gender = Gender.Male,
                    DateOfBirth = DateTime.Parse("1927-08-20")
                },
                new User
                {
                    Id = 3,
                    GivenName = "Reinaldo",
                    FamilyName = "Nisbet",
                    BossId =  1,
                    Title = "VP of Technology",
                    Gender = Gender.Male,
                    DateOfBirth = DateTime.Parse("1929-02-07")
                },
                new User
                {
                    Id = 4,
                    GivenName = "Alleen",
                    FamilyName = "Bufford",
                    BossId = 1,
                    Title = "VP of HR",
                    Gender = Gender.Unspecified,
                    DateOfBirth = DateTime.Parse("1932-06-13")
                },
                new User
                {
                    Id = 5,
                    GivenName = "Kristyn",
                    FamilyName = "Klopfer",
                    BossId = 2,
                    Title = "Director of Marketing",
                    Gender = Gender.Female,
                    DateOfBirth = DateTime.Parse("1936-09-26")
                },
                new User
                {
                    Id = 6,
                    GivenName = "Sophie",
                    FamilyName = "Duhon",
                    BossId = 3,
                    Title = "Tech Manager",
                    Gender = Gender.Male,
                    DateOfBirth = DateTime.Parse("1937-11-23")
                },
                new User
                {
                    Id = 7,
                    GivenName = "Suanne",
                    FamilyName = "Mirabal",
                    BossId = 3,
                    Title = "Tech Manager",
                    Gender = Gender.Female,
                    DateOfBirth = DateTime.Parse("1948-04-05")
                },
                new User
                {
                    Id = 9,
                    GivenName = "Norah",
                    FamilyName = "Maslowski",
                    BossId =  4,
                    Title = "Tech Manager",
                    Gender = Gender.Unspecified,
                    DateOfBirth = DateTime.Parse("1966-10-13")
                },
                new User
                {
                    Id = 10,
                    GivenName = "Gertrudis",
                    FamilyName = "Redford",
                    BossId = 6,
                    Title = "Tech Lead",
                    Gender = Gender.Female,
                    DateOfBirth = DateTime.Parse("1967-08-25")
                },
                new User
                {
                    Id = 11,
                    GivenName = "Donovan",
                    FamilyName = "Tobey",
                    BossId = 6,
                    Title = "Tech Lead",
                    Gender = Gender.Male,
                    DateOfBirth = DateTime.Parse("1968-12-26")
                },
                new User
                {
                    Id = 12,
                    GivenName = "Rich",
                    FamilyName = "Vermeulen",
                    BossId = 9,
                    Title = "Trainer Lead",
                    Gender = Gender.Male,
                    DateOfBirth = DateTime.Parse("1969-10-16")
                },
                new User
                {
                    Id = 13,
                    GivenName = "Santo",
                    FamilyName = "Knupp",
                    BossId = 9,
                    Title = "HR Manager",
                    Gender = Gender.Male,
                    DateOfBirth = DateTime.Parse("1972-10-16")
                },
                new User
                {
                    Id = 14,
                    GivenName = "Jazmin",
                    FamilyName = "Grooms",
                    BossId = 12,
                    Title = "Trainer",
                    Gender = Gender.Female,
                    DateOfBirth = DateTime.Parse("1974-03-23")
                },
                new User
                {
                    Id = 15,
                    GivenName = "Annelle",
                    FamilyName = "Cheeks",
                    BossId = 13,
                    Title = "Recruiter",
                    Gender = Gender.Female,
                    DateOfBirth = DateTime.Parse("1978-08-25")
                },
                new User
                {
                    Id = 16,
                    GivenName = "Eliza",
                    FamilyName = "Harshaw",
                    BossId = 12,
                    Title = "Trainer",
                    Gender = Gender.Unspecified,
                    DateOfBirth = DateTime.Parse("1979-08-21")
                },
                new User
                {
                    Id = 17,
                    GivenName = "Xiomara",
                    FamilyName = "Broaddus",
                    BossId = 8 ,
                    Title = "Senior Software Developer",
                    Gender = Gender.Unspecified,
                    DateOfBirth = DateTime.Parse("1980-02-09")
                },
                new User
                {
                    Id = 18,
                    GivenName = "Erminia",
                    FamilyName = "Jungers",
                    BossId = 11,
                    Title = "Software Developer",
                    Gender = Gender.Unspecified,
                    DateOfBirth = DateTime.Parse("1981-09-08")
                },
                new User
                {
                    Id = 19,
                    GivenName = "Maria",
                    FamilyName = "Moffatt",
                    BossId = 10,
                    Title = "Software Developer",
                    Gender = Gender.Female,
                    DateOfBirth = DateTime.Parse("1984-03-18")
                },
                new User
                {
                    Id = 20,
                    GivenName = "Tammera",
                    FamilyName = "Grimaldo",
                    BossId = 10,
                    Title = "Senior Software Developer",
                    Gender = Gender.Female,
                    DateOfBirth = DateTime.Parse("1990-09-24")
                },
                new User
                {
                    Id = 21,
                    GivenName = "Sharyl",
                    FamilyName = "Das",
                    BossId = 10,
                    Title = "Software Developer",
                    Gender = Gender.Female,
                    DateOfBirth = DateTime.Parse("1992-06-18")
                },
                new User
                {
                    Id = 22,
                    GivenName = "Shan",
                    FamilyName = "Harlan",
                    BossId = 8,
                    Title = "UI Developer",
                    Gender = Gender.Unspecified,
                    DateOfBirth = DateTime.Parse("1993-11-15")
                },
                new User
                {
                    Id = 23,
                    GivenName = "Mariah",
                    FamilyName = "Almeida",
                    BossId = 11,
                    Title = "QA Tester",
                    Gender = Gender.Female,
                    DateOfBirth = DateTime.Parse("1997-03-23")
                },
                new User
                {
                    Id = 24,
                    GivenName = "Darnell",
                    FamilyName = "Kerfien",
                    BossId = 11,
                    Title = "QA Tester",
                    Gender = Gender.Male,
                    DateOfBirth = DateTime.Parse("1998-11-10")
                },
                new User
                {
                    Id = 25,
                    GivenName = "Janell",
                    FamilyName = "Vierra",
                    BossId = 11,
                    Title = "QA Tester",
                    Gender = Gender.Female,
                    DateOfBirth = DateTime.Parse("2004-04-22")
                }
            };
            #endregion
        }
    }
    StreetAddressData.cs
    using System.Collections.Generic;
    using System.Linq;
    using DataAccess.BO;
    
    namespace DataAccess
    {
        public class StreetStreetAddressData
        {
            #region
            private static readonly List<StreetAddress> Addresses = new List<StreetAddress>
            {
                new StreetAddress{ Id = 1, PersonId = 1, Street = "62 Durham Court", City = "Garfield", State="NJ", Zip ="07026" },
                new StreetAddress{ Id = 2, PersonId = 1, Street = "179 Cambridge Court", City = "Chippewa Falls", State="WI", Zip ="54729" },
                new StreetAddress{ Id = 3, PersonId = 1, Street = "573 Route 5", City = "Memphis", State="TN", Zip ="38106" },
                new StreetAddress{ Id = 4, PersonId = 2, Street = "173 Monroe Street", City = "Powhatan", State="VA", Zip ="23139" },
                new StreetAddress{ Id = 5, PersonId = 5, Street = "47 Brookside Drive", City = "Westport", State="CT", Zip ="06880" },
                new StreetAddress{ Id = 6, PersonId = 6, Street = "628 Creekside Drive", City = "Mankato", State="MN", Zip ="56001" },
                new StreetAddress{ Id = 7, PersonId = 7, Street = "581 Lexington Court", City = "Sykesville", State="MD", Zip ="21784" },
                new StreetAddress{ Id = 8, PersonId = 11, Street = "860 Deerfield Drive", City = "Muskego", State="WI", Zip ="53150" },
                new StreetAddress{ Id = 9, PersonId = 13, Street = "189 Elizabeth Street", City = "Ashtabula", State="OH", Zip ="44004" },
                new StreetAddress{ Id = 10, PersonId = 13, Street = "945 Rosewood Drive", City = "Fairfield", State="CT", Zip ="06824" },
                new StreetAddress{ Id = 11, PersonId = 13, Street = "958 Hill Street", City = "Roy", State="UT", Zip ="84067" },
                new StreetAddress{ Id = 12, PersonId = 14, Street = "687 Westminster Drive", City = "Desoto", State="TX", Zip ="75115" },
                new StreetAddress{ Id = 13, PersonId = 15, Street = "530 Forest Drive", City = "Mc Lean", State="VA", Zip ="22101" },
                new StreetAddress{ Id = 14, PersonId = 17, Street = "766 Cambridge Road", City = "Portage", State="IN", Zip ="46368" },
                new StreetAddress{ Id = 15, PersonId = 17, Street = "788 Ivy Court", City = "Sunnyside", State="NY", Zip ="11104" },
                new StreetAddress{ Id = 16, PersonId = 19, Street = "750 Ashley Court", City = "Selden", State="NY", Zip ="11784" },
                new StreetAddress{ Id = 17, PersonId = 20, Street = "612 Harrison Street", City = "Winter Haven", State="FL", Zip ="33880" },
                new StreetAddress{ Id = 18, PersonId = 22, Street = "780 Locust Lane", City = "Saint Petersburg", State="FL", Zip ="33702" },
                new StreetAddress{ Id = 19, PersonId = 22, Street = "896 Chestnut Street", City = "Tallahassee", State="FL", Zip ="32303" },
                new StreetAddress{ Id = 20, PersonId = 24, Street = "321 Roosevelt Avenue", City = "Dunedin", State="FL", Zip ="34698" },
            };
    #endregion
        }
    }

    UserContrller.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Net;
    using System.Net.Http;
    using System.Web.Http;
    using DataAccess;
    
    
    namespace SrEngineer.Controllers
    {
        public class UserController : ApiController
        {
           
            
    
            /// <summary>
            /// Get Person By ID
            /// </summary>
            /// <param name="id">Person id </param>
            /// <returns></returns>
            // GET: api/User/GetByID/5
           [Route("api/User/GetByID/{id}")]
            public IHttpActionResult GetById(int id)
            {
                DataAccess.BO.User person = PersonDataAccess.Data.FirstOrDefault(p => p.Id == id);
                if (person != null)
                {
                    return Ok(person);
                }
                else
                {
                    return NotFound();
                }
            } 
        }
    }

    Sorry for the basic question, but How can I achieve this JSON Schema?

    {
    	"User": {
    		"Id" : "1",
            "FirstName" : "Winfred",
            "LastName" : "Fetzer",
    		"BossName" : null,
    	    "Title" : "CEO",
            "DateOfBirth" : "1927-01-29",
            "Gender" : "Female",
            "Addresses" : [{
    			"Id" : 1,
    			"Street" :  "62 Durham Court",
    			"City" : "Garfield",
    			"State" : "NJ",
    			"Zip" : "07026"
    		},{
    			"Id" : 2,
    			"Street" :  "179 Cambridge Court",
    			"City" : "Chippewa Falls",
    			"State" : "WI",
    			"Zip" : "54729"
    		},{
    			"Id" : 3,
    			"Street" :  "573 Route 5",
    			"City" : "Memphis",
    			"State" : "TN",
    			"ZipCode" : "38106"
    		}]
    	}
    }


    • Edited by Karanke Tuesday, December 18, 2018 12:05 AM Removed unnecessary code
    Tuesday, December 18, 2018 12:04 AM

All replies

  • Probably one of the simple solutions is to define another User class (maybe in a different namespace) that corresponds to required JSON, for example:

    class User

    {

       public int Id;

       public string FirstName;

       public string LastName;

       . . .

       public StreetAddress [ ] Addresses;

    }

     

    Then make such object from your person variable. Also fill the Addresses member:

       user.Addresses = StreetStreetAddressData.Addresses.Where( a => a.PersonId == person.Id).ToArray( );

     

    In order to exclude the PersonId from StreetAddress, use an attribute like [NonSerialised], [ScriptIgnore], [JsonIgnore], or omit [DataMember], depending on certain details of your implementation.






    Tuesday, December 18, 2018 6:30 AM
  • You should be using the DTO pattern with the DTO or DTO(s) being known by the WebAPI client and the WebAPI service, which is usually done by having  a classlib project called Entities where the DTO(s) are kept, and the client and service projects have reference to Entities and know what the DTO(s) are about.

    https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp

    https://www.codeproject.com/Articles/1050468/Data-Transfer-Object-Design-Pattern-in-Csharp

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5

    public class DTOAddress { // its public propeties } public class DTOUser { // its public propeties //but an additional public property for DtoAddresses //that belong to a DtoUser. public List<DtoAddress> Addresses {get; set;} }


    Then you  just send DtoUser that holds all the data to the client that is Json based the default for WebAPI and deserialize the Json back into the DTO(s) on the client side. I gave you some example code so you can see. It's kind of in the ballpark of what you are trying to do.

    HTH

    And WebAPI can be discussed at  the WebAPI forum at ASP.NET forums.

    http://forums.asp.net/

    namespace Entities
    {
        public class DtoCacheRoot
        {
            public DtoCache DtoCache { get; set; }
        }
    }
    
    ===================================================
    
    namespace Entities
    {
        public class DtoCache
        {
            public List<DtoProjectType> ProjectTypes { get; set; } = new List<DtoProjectType>();
            public List<DtoStatus> Statuses { get; set; } = new List<DtoStatus>();
            public List<DtoResource> Resources { get; set; } = new List<DtoResource>();
            public List<DtoDuration> Durations { get; set; } = new List<DtoDuration>();
        }
    }

    Service-side

    using DAL;
    using Entities;
    using Microsoft.AspNetCore.Mvc;
    
    namespace ProgMgmntCore2Api.Controllers
    {
        [Produces("application/json")]
        [Route("api/[controller]")]
        [ApiController]
        public class CacheController : ControllerBase,  ICacheController
        {
            private readonly IDaoCache _daoCache;
    
            public CacheController(IDaoCache daoCache)
            {
                _daoCache = daoCache;
            }
    
            [HttpGet]
            public CacheResponse Get_Cache()
            {
                var resp = new CacheResponse();
    
                var cache = _daoCache.GetCache();
    
                resp.DtoCache.Durations = cache.Durations;
                resp.DtoCache.ProjectTypes = cache.ProjectTypes;
                resp.DtoCache.Resources = cache.Resources;
                resp.DtoCache.Statuses = cache.Statuses;
    
                return resp;
            }
        }
    }

    namespace Entities
    {
        public class CacheResponse
        {
            public DtoCache DtoCache { get; set; } = new DtoCache();
        }
    }
    

    namespace DAL
    {
        public interface IDaoCache
        {
            DtoCache GetCache();
        }
    }
    
    ============================================
    using System.Collections.Generic;
    using System.Linq;
    using DAL.Models.DB;
    using Entities;
    using Microsoft.Extensions.Logging;
    using Microsoft.Extensions.Options;
    
    namespace DAL
    {
        public class DaoCache : IDaoCache
        {
            private readonly IOptions<ConnectionStrings> _options;
          
            public DaoCache(IOptions<ConnectionStrings> options)
            {
                _options = options;
            }
    
            public DtoCache GetCache()
            {
                var dtocache = new DtoCache
                {
                    ProjectTypes = new List<DtoProjectType>(),
                    Statuses = new List<DtoStatus>(),
                    Resources = new List<DtoResource>(),
                    Durations = new List<DtoDuration>()
                };
    
                using (var context = new ProjectManagementContext(_options))
                {
                    var projectypes = (from a in context.ProjectTypes select a).ToList();
                    CreateProjectTypes(dtocache, projectypes);
    
                    var statuses = (from a in context.Statuses select a).ToList();
                    CreateStatuses(dtocache, statuses);
    
                    var resources = (from a in context.Resources select a).ToList();
                    CreateResources(dtocache, resources);
    
                    var durations = (from a in context.Durations select a).ToList();
                    CreateDurations(dtocache, durations);
                }
    
                return dtocache;
            }
    
            private static void CreateProjectTypes(DtoCache dtocache, List<ProjectTypes> projectypes)
            {
                foreach (var pt in projectypes)
                {
                    var dto = new DtoProjectType
                    {
                        ProjectTypeId = pt.ProjectTypeId,
                        Text = pt.Text,
                        Value = pt.Value
                    };
    
                    dtocache.ProjectTypes.Add(dto);
                }
            }
    
            private static void CreateStatuses(DtoCache dtocache, List<Statuses> statuses)
            {
                foreach (var st in statuses)
                {
                    var dto = new DtoStatus()
                    {
                        StatusId = st.StatusId,
                        Text = st.Text,
                        Value = st.Value
                    };
    
                    dtocache.Statuses.Add(dto);
                }
            }
    
            private static void CreateResources(DtoCache dtocache, List<Resources> resources)
            {
    
                foreach (var rc in resources)
                {
                    var dto = new DtoResource()
                    {
                        ResourceId = rc.ResourceId,
                        Text = rc.Text,
                        Value = rc.Value
                    };
    
                    dtocache.Resources.Add(dto);
                }
            }
    
            private static void CreateDurations(DtoCache dtocache, List<Durations> durations)
            {
    
                foreach (var du in durations)
                {
                    var dto = new DtoDuration()
                    {
                        DurationId = du.DurationId,
                        Text = du.Text,
                        Value = du.Value
                    };
    
                    dtocache.Durations.Add(dto);
                }
            }
        }
    }
    

    client-side

    public DtoCache GetCacheApi()
            {
                var dtocache = new DtoCache();
    
                using (var client = new HttpClient())
                {
                    var uri = new Uri("http://progmgmntcore2api.com/api/cache");
    
                    var response = client.GetAsync(uri).Result;
    
                    if (!response.IsSuccessStatusCode)
                        throw new Exception(response.ToString());
    
                    var responseContent = response.Content;
                    var responseString = responseContent.ReadAsStringAsync().Result;
    
                    var deserialized = JsonConvert.DeserializeObject<DtoCacheRoot>(responseString);
    
                    dtocache.ProjectTypes = deserialized.DtoCache.ProjectTypes;
                    dtocache.Durations = deserialized.DtoCache.Durations;
                    dtocache.Statuses = deserialized.DtoCache.Statuses;
                    dtocache.Resources = deserialized.DtoCache.Resources;
                }
    
                return dtocache;
            }
    

    namespace Entities
    {
        public class DtoCacheRoot
        {
            public DtoCache DtoCache { get; set; }
        }
    }
    


    • Edited by DA924x Tuesday, December 18, 2018 6:53 AM
    Tuesday, December 18, 2018 6:35 AM
  • Hi Karanke,

    Thank you for posting here.

    If you want to convert list to json, I make a simple example for your reference.

    using Newtonsoft.Json.Linq;
    using System;
    using System.Collections.Generic;
    using System.Linq.Expressions;
    using System.Web.Script.Serialization;
    
    namespace ConsoleApp
    {
        public class User
        {
            public int Id { get; set; }
            public string GivenName { get; set; }
            public string FamilyName { get; set; }
            public int? BossId { get; set; }
            public string Title { get; set; }
            public DateTime DateOfBirth { get; set; }
    
        }
        class Program
        {
            static void Main(string[] args)
            {
                List<User> Data = new List<User>
               {
                new User
                {
                    Id = 8,
                    GivenName = "Trinh",
                    FamilyName = "Montejano",
                    BossId = 3,
                    Title = "Tech Manager",
                    DateOfBirth = DateTime.Parse("1966-09-27")
                },
                new User
                {
                    Id = 1,
                    GivenName = "Winfred",
                    FamilyName = "Fetzer",
                    BossId = null,
                    Title = "CEO",
                    DateOfBirth = DateTime.Parse("1927-01-29")
                },
                new User
                {
                    Id = 2,
                    GivenName = "Erich",
                    FamilyName = "Dandrea",
                    BossId = 1,
                    Title = "VP of Marketing",
                    DateOfBirth = DateTime.Parse("1927-08-20")
                },
                new User
                {
                    Id = 3,
                    GivenName = "Reinaldo",
                    FamilyName = "Nisbet",
                    BossId =  1,
                    Title = "VP of Technology",
                    DateOfBirth = DateTime.Parse("1929-02-07")
                },
                new User
                {
                    Id = 4,
                    GivenName = "Alleen",
                    FamilyName = "Bufford",
                    BossId = 1,
                    Title = "VP of HR",
                    DateOfBirth = DateTime.Parse("1932-06-13")
                }};
                var jsonSerialiser = new JavaScriptSerializer();
                var json = jsonSerialiser.Serialize(Data);
                Console.WriteLine(json);
                Console.ReadKey();
            }
        }
    }
    
    

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, December 18, 2018 6:54 AM
    Moderator
  • This is the by far the best example but it lacks a couple of things

    1. It returns JSON inside an XML Tree
    2. It does not map with Addresses
    This XML file does not appear to have any style information associated with it. The document tree is shown below.
    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
    {"Id":1,"BossId":null,"Title":"CEO","GivenName":"Winfred","FamilyName":"Fetzer","DateOfBirth":"\/Date(-1354599000000)\/","Gender":2}
    </string>

    Tuesday, December 18, 2018 3:50 PM
  • can you ELI5 with an example? thank you
    Tuesday, December 18, 2018 4:01 PM
  • Probably one of the simple solutions is to define another User class (maybe in a different namespace) that corresponds to required JSON, for example:

    class User

    {

       public int Id;

       public string FirstName;

       public string LastName;

       . . .

       public StreetAddress [ ] Addresses;

    }

     

    Then make such object from your person variable. Also fill the Addresses member:

       user.Addresses = StreetStreetAddressData.Addresses.Where( a => a.PersonId == person.Id).ToArray( );

     

    In order to exclude the PersonId from StreetAddress, use an attribute like [NonSerialised], [ScriptIgnore], [JsonIgnore], or omit [DataMember], depending on certain details of your implementation.






    Can you please provide a working Example?
    Tuesday, December 18, 2018 4:21 PM
  • This is the by far the best example but it lacks a couple of things

    1. It returns JSON inside an XML Tree
    2. It does not map with Addresses
    This XML file does not appear to have any style information associated with it. The document tree is shown below.
    <string xmlns="http://schemas.microsoft.com/2003/10/Serialization/">
    {"Id":1,"BossId":null,"Title":"CEO","GivenName":"Winfred","FamilyName":"Fetzer","DateOfBirth":"\/Date(-1354599000000)\/","Gender":2}
    </string>

    It's a simple task if using the DTO pattern. You should learn how to use the pattern in working with ASP.NET WebAPI.

    https://docs.microsoft.com/en-us/aspnet/web-api/overview/data/using-web-api-with-entity-framework/part-5

    Even the ASP.NET WebAPI tutorial is using the DTO pattern. Hmm, I wonder why? :)

    Why are you not posting to the forum?

    https://forums.asp.net/1246.aspx/1?Web+API

    Tuesday, December 18, 2018 6:13 PM