I am trying to return some data as json from an action method.
I have an employee object that looks like this:
public class Employee
{
public int EmployeeID {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
//Other irrelevant properties
}
Then I have a view model as follows
public Class EmployeeViewModel
{
public Employee Supervisor{get; set;}
public List<EmployeeViewModel> Employees
}
I need to return a json object that looks exactly like this:
{id: 1, name: John, children: [
{id: 1, name: Joe, children: []},
{id: 1, name: Rob, children: []}
]}
For now I only need to go to the second level as above, returning and supervisor and their staff members beneath them.
How would I go about returning this in my action method(I have the viewModel object hydrated already I just need to return it as json). My problem so far has been that the children
property does not get populated.
You will be amazed at how simple this is. Just set up your model objects so that they have the correct properties. With the JSON string you are trying to achieve, you don't want a view model because you appear to want the top level object to contain properties of employee. Whereas if you use a viewmodel object then the top level object will be the view model object, and employee will be a property of that object.
Instead I think you want the top level object to be an employee with a property that is a list of children (child objects). Child objects also have a property called children. Which could be populated recursively. Building the object is your responsibility, but I did provide some pseudo-code with pseudo-data to get you started.
public Class Employee
{
public int EmployeeID {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public List<Child> Children {get; set;}
}
public Class Child
{
public int ChildID {get; set;}
public string FirstName {get; set;}
public string LastName {get; set;}
public List<Child> Children {get; set;{
}
Now your action method. Did you know you could just return JsonResult? Do this:
public JsonResult GetJSON()
{
//Build employee object and add children to list. Something like the following pseudo-code:
List<Child> childrenList = new List<Child>
{
new Child
{
ChildID = //some id,
FirstName = "Joe",
LastName = "Smith"
// Add children to list.
},
// Add more children to list.
}
Employee emp = new Employee
{
EmployeeID = 123,
FirstName = "John",
LastName = "Doe",
Children = childrenList
};
Return Json(emp);
}
This JSON would look like:
{ "EmployeeID":"123", "FirstName":"John", "LastName":"Doe", "Children":[
{ "ChildID":"someid", "FirstName":"Joe", "LastName":"Smith", Children [] },
{ etc... }
] }
If you are not familiar with JSON much then you should know that quotation marks around both the variable and the name ensure that nothing is misinterpreted. MVC does it for you, and quite well. It will turn the list property of employee into a JSON array without any work on your part and it will format the JSON neatly and readably.
Now with MVC 3 you can model-bind to JSON also. If you make a request with a json object included, MVC 3 will automatically bind it's properties to an employee object. So if you posted the same JSON string that I listed above, your action method could look like this:
public ActionResult SampleMethod(Employee emp)
{
//emp would be the same object you sent as JSON earlier and are now sending back :D
}
NOTE: You might consider changing Employee
to Person
, and giving it a property called Children
of type List<Person>
. That way you would be combining the Employee
and Child
classes into one. But naturally I can't see all your code, so maybe you do have enough unique properties to merit the two classes.