Web API Returning Nested Json Values

Web API Returning Nested JSON Values

  • I will assume that the JSON structure is the source of truth here not the models (TeamWithPlayers/Players) - see my comments.

  • My solution assumes that you are using Entity Framework to retrieve the data from the database because I am using "Include" method, but can replace it to use "Join".

1- Define TeamDto and PlayerDto classes to be like :

public class TeamDto
{
public int TeamId { get; set; }
public string TeamName { get; set; }
public IEnumerable<PlayerDto> TeamPlayers { get; set; }
}

public class PlayerDto
{
public int PlayerId { get; set; }
public string PlayerName { get; set; }
}

2- Your TeamsController will be like this:

public class TeamsController : ApiController
{
private readonly TeamDbContext _dbContext = new TeamDbContext();

// GET api/teams
public IEnumerable<TeamDto> GetTeamsAndPlayers()
{
var teams = _dbContext
.Teams
.Include("Players") // Load the players associated with each Team, (this depends on your declaration, but you mentioned that there is a FK from Player => TeamId)
// you can use the join if you like or if you don't use entity framework where you cannot call Include, but the following code will stay the same
.Select(t => new TeamDto
{
TeamId = t.TeamId,
TeamName = t.TeamName,
TeamPlayers = t.Players.Select(p => new PlayerDto
{
PlayerId = p.PlayerId,
PlayerName = p.PlayerName
})
}).ToList();

return teams;
}
}

Hope that helps.

How Web API Return Nested JSON Values by HttpPost call from database?

If you getting request JSON as:

[
{
"Agent_Code": "123456",
"Name": "Miss Sara Manger",
"NickName": "Sara",
"BirthDay": "19690825",
"CardID": "9999999999",
"Address": "870 Goldleaf Lane Lyndhurst NJ New Jersey 07071",
"Mobile": "000000000",
"Email": "utv9hgn3h0k@classesmail.com",
"Bank": [
{
"AcctName": "Miss Sara Manger",
"Acctno": "9999999999",
"Bank": "KBANK"
}
]
}
]

Then the CountDashReq class should be:

public class Bank
{
public string AcctName { get; set; }
public string Acctno { get; set; }
public string Bank { get; set; }
}

public class CountDashReq
{
public string Agent_Code { get; set; }
public string Name { get; set; }
public string NickName { get; set; }
public string BirthDay { get; set; }
public string CardID { get; set; }
public string Address { get; set; }
public string Mobile { get; set; }
public string Email { get; set; }
public List<Bank> Bank { get; set; }
}

In controller method:

[HttpPost]
public List<Models.AgentDto> TestJSON(IList<Models.CountDashReq> model)
{
// Your code
}

WEB API to return Nested Array JSON Result C#

Probably the easiest way would be to create a custom JsonConverter and transform your response inside to your required format:

public class ResponseConverter : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(Response);

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) => throw new NotImplementedException();

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
Response originalResponse = (Response)value;
writer.WriteStartObject();
writer.WritePropertyName(nameof(originalResponse.Status));
writer.WriteValue(originalResponse.Status);
writer.WritePropertyName(nameof(originalResponse.Series));
writer.WriteStartArray();
foreach (var val in originalResponse.Series)
{
writer.WriteStartArray();
writer.WriteValue(val.ColorCode);
writer.WriteValue(val.ColorVal);
writer.WriteEndArray();
}
writer.WriteEndArray();
writer.WriteEndObject();
}
}

Then, you can decorate your Response class with a special attribute to denote that it should be serialized with this converter:

[JsonConverter(typeof(ResponseConverter))]
public class Response
{
public string Status { get; set; }
public List<SampleData> Series { get; set; }
}

how to get the nested JSON objects from SQL table in ASP.Net Web API

Not sure how you plan to use the Json as there is no connection between the parent list and child list. But here is how you can have the JSON from SQL Server:

#Create Classes of type parent and child

#Create an object called myobject with the two array/list properties - parent and childs

#Query SQL DB and populate the myobject object

#Transform the myobject object into JSON and send from API action

public class parent
{
public string name { get; set; }
public string designation { get; set; }
public string state { get; set; }
public bool active { get; set; }
}

public class child
{
public string name { get; set; }
public string designation { get; set; }
public string state { get; set; }
public bool active { get; set; }
public bool hasChilds { get; set; }
}

public class myboject
{
public List<Parent> parent { get; set; }
public List<Child> childs { get; set; }
}

myboject myboj = new myboject();
myboj.parent = new List<Parent>();
myboj.child = new List<Child>();

//Query your sql server database and populate the myboj.parent and myboj.child with proper data

Then do the Json transformation:

return Newtonsoft.Json.JsonConvert.SerializeObject(myboj);

That will transform the myObj into a json object and return.

How to serve(GET) Complex(Nested) JSON from C# Web API Visual Studio 2017 RTM that has a Many-to-Many relationship?

After many hours of trying to use .Include() I went back to DTOs.

I arrived at a solution, but I don't know if it could be used later when I need to alter the Application get() method.

My solution starts from my original code before Bchir Med Amine's suggestions(It works with his code too, but I went back for simplicity).

First Create a DTO.cs file in your models folder. in it put these classes:

public class EmployeeDTO
{

public string LName { get; set; }
public string FName { get; set; }
public string Title { get; set; }


//Navigation Property
public List<EmployeeApplicationsDTO> EmployeeApplicationsDTO { get; set; }
}

public class EmployeeApplicationsDTO
{
public Application Application { get; set; }

}

Next in the EmployeesController's GetEmployees() method use this code:

return _context.Employees.Select(e => new EmployeeDTO
{
LName = e.LName,
FName = e.FName,
Title = e.Title,
EmployeeApplicationsDTO = e.EmployeeApplications.Select(ea => new EmployeeApplicationsDTO
{
Application = ea.Application
}).ToList()
}).ToList();

That's it. Here's the JSON:

[{
"lName": "Doe",
"fName": "John",
"title": "Senior Software Engineer",
"employeeApplicationsDTO": [{
"application": {
"applicationId": 1,
"name": "Application 1",
"description": "Description 1",
"employeeApplications": null
}
},
{
"application": {
"applicationId": 2,
"name": "Application 2",
"description": "Description 2",
"employeeApplications": null
}
}]
},
{
"lName": "Smith",
"fName": "Jack",
"title": "Project Manager",
"employeeApplicationsDTO": [{
"application": {
"applicationId": 2,
"name": "Application 2",
"description": "Description 2",
"employeeApplications": null
}
},
{
"application": {
"applicationId": 3,
"name": "Application 3",
"description": "Description 3",
"employeeApplications": null
}
}]
}]

As you can see it is not perfect, but it will allow me to continue developing the rest of the app.

The DTO allows me to show only the data I want to show. But something is still off about my object structure. To get applications that an engineer works on I have to drill into it:

Employee[x].employeeApplicationDTO[y].application.name

The .application. doesn't seem necessary, but I can't solve that now.

I post this as an answer because it's the progress I have made, if someone else comes up with a better solution I will try it and give them credit.

Can't send via POST a nested JSON with null Subclass Net Core API

since you are using net 6 , you have to make everything nullable, this is why you have the error
you can try this

public class Location
{
.....
public string? StreetID{ get; set; }
public virtual Street? Street{ get; set; }
}

but I recommend you to fix everything, by removing nullable from your project properties, otherwise it will be repeating and repeating

<PropertyGroup>
<TargetFramework>net6.0</TargetFramework>
<!--<Nullable>enable</Nullable>-->
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>

then fix the program, you added controllers twice, it should be once

builder.Services.AddControllers()
.AddNewtonsoftJson(options =>
options.SerializerSettings.ContractResolver =
new CamelCasePropertyNamesContractResolver());

then fix your http request , you don't need any byte array, since you are sending json

    string requestUri = "https://localhost:5001/Customers/CreateLocation";
using HttpClient client = new HttpClient();

client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var json = JsonConvert.SerializeObject(location);
var content = new StringContent(json, UTF8Encoding.UTF8, "application/json");

var response = await client.PostAsync(requestUri, content);

if (response.IsSuccessStatusCode)
{
var stringData = await response.Content.ReadAsStringAsync();
var result = JsonConvert.DeserializeObject<object>(stringData);
}

and fix the post action

         [HttpPost]
[Route("CreateLocation")]
public IActionResult CreateOrt([FromBody] Location location)


Related Topics



Leave a reply



Submit