0

I'm trying to get my web service, written in .NET MVC5, to return JSON that I can consume in an iOS app. I thought I'd already succeeded, but looking more closely at the returned data - and bear in mind that this is all new to me, so forgive my terminology - it look as if I'm getting a JSON array rather than a JSON object.

This, I think, is causing issues when I follow online tutorials which show how to convert JSON objects into dictionaries in Swift for displaying in an app. As you can see from the output sample below, my JSON begins with [{"FirstName":"John"..., effectively launching straight into an array of People, when I think I want it to start something like {"People":[{"FirstName":"John"...

How can I get the JSON returned to be an object rather than just an array of people? I'm hoping I'm nearly there and perhaps just need to change a type somewhere?

Model:

public class PersonModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string DepartmentName { get; set; }

    public IEnumerable<PhoneNumberModel> PhoneNumbers { get; set; }
}

Controller:

public class PersonController : ApiController
{
    public IEnumerable<PersonModel> GetAllPersons()
    {
        List<PersonModel> person;
        using (var context = new ContactsContext())
        {
            person = context.People.Include("PhoneNumbers.PhoneNumberType1").ToList()
                .Select(p => new PersonModel
                {
                    FirstName = p.FirstName,
                    LastName = p.LastName,
                    DepartmentName = p.Department1.Name,
                    PhoneNumbers = p.PhoneNumbers.Select(x => new PhoneNumberModel
                    {
                        PhoneNumberTypeName = x.PhoneNumberType1.Description,
                        TelephoneNumber = x.PhoneNumber1
                    })
                }).ToList();
        }

        return person;
    }
}

Output:

[{
"FirstName": "John",
"LastName": "Smith",
"DepartmentName": "Accounts",
"PhoneNumbers": [{
    "PhoneNumberTypeName": "Office",
    "TelephoneNumber": "12345"
    }, {
    "PhoneNumberTypeName": "Mobile",
    "TelephoneNumber": "54321"
    }]
}, {
    "FirstName": "Jane",
    "LastName": "Harris",
    "DepartmentName": "HR",
    "PhoneNumbers": [{
        "PhoneNumberTypeName": "Mobile",
        "TelephoneNumber": "98765"
    }]
}]
1
  • 2
    The generated JSON is correct - Your return type for the Action is IEnumerable<PersonModel> which is a collection, so it will always be converted to an Array in JSON. Commented Jun 9, 2016 at 9:23

2 Answers 2

2

Your GetAllPersons method returns an IEnumerable (i.e. a collection of PersonModel) so it will be serialized to it's JSON counterpart (i.e. a collection of JSON objects). If you want to wrap the collection in a JSON object, so it becomes:

{
   "People": [
      {
         "FirstName": "trashr0x",
         "LastName": "StackOverflow",
         "DepartmentName": "MVC",
         "PhoneNumbers": [
            {
               "PhoneNumberTypeName": "Work",
               "TelephoneNumber": "123456"
            }
         ]
      }
   ]
}

...then simply do the same with your model in C#: make a PeopleModel class having a People property of type IEnumerable<PersonModel>:

public class PeopleModel
{
    public IEnumerable<PersonModel> People { get; set; }
}

You can then instantiate a PeopleModel instance, set PeopleModel.People to your IEnumerable<PersonModel> and return PeopleModel instead.

Sign up to request clarification or add additional context in comments.

2 Comments

This did the trick, thanks! Is it to be expected that doing this would return the data much more slowly? Because it is!
Hey, you're welcome. It normally shouldn't - I can't tell without having a look at your implementation.
0

Using HttpResponseMessage

public HttpResponseMessage GetAllPersons()
{
    List<PersonModel> person;
    using (var context = new ContactsContext())
    {
        person = context.People.Include("PhoneNumbers.PhoneNumberType1").ToList()
            .Select(p => new PersonModel
            {
                FirstName = p.FirstName,
                LastName = p.LastName,
                DepartmentName = p.Department1.Name,
                PhoneNumbers = p.PhoneNumbers.Select(x => new PhoneNumberModel
                {
                    PhoneNumberTypeName = x.PhoneNumberType1.Description,
                    TelephoneNumber = x.PhoneNumber1
                })
            }).ToList();
    } 
    HttpResponseMessage response = 
    Request.CreateResponse(HttpStatusCode.OK, new { People = person });
    return response;  
  }

Using IHttpActionResult

public IHttpActionResult GetAllPersons()
    {
        List<PersonModel> person;
        using (var context = new ContactsContext())
        {
            person = context.People.Include("PhoneNumbers.PhoneNumberType1").ToList()
                .Select(p => new PersonModel
                {
                    FirstName = p.FirstName,
                    LastName = p.LastName,
                    DepartmentName = p.Department1.Name,
                    PhoneNumbers = p.PhoneNumbers.Select(x => new PhoneNumberModel
                    {
                        PhoneNumberTypeName = x.PhoneNumberType1.Description,
                        TelephoneNumber = x.PhoneNumber1
                    })
                }).ToList();
        } 
        return Ok(new { People = person }); 
    }

see this link for more info

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.