Sylvain Girard
Sylvain Girard

Reputation: 388

.NET Core Web API serialization issue

This is an excerpt from a straightforward API controller:

[Route("api/cities")]
public class CitiesController : BaseController
{
    internal protected ICityRepository _cityRepository;
    public CitiesController(ICityRepository cityRepository) : base()
    {
        _cityRepository = cityRepository;
    }

    // GET: api/Cities
    [HttpGet]
    public IEnumerable<City> Get()
    {
        var cities = _cityRepository.GetAll();
        return cities;
    }

    // GET: api/Cities/5
    [HttpGet("{id}", Name = "GetCity")]
    public IActionResult Get(Guid id)
    {
        City city = _cityRepository.Get(id);
        if (city == null)
        {
            return NotFound();
        }

        return new ObjectResult(city);
    }

BaseController does nothing more than inherit from Controller at the moment. Whenever I call api/cities or api/cities/E4477C67-894E-492C-95DE-001DC73730A1 I get something like this in return:

{
    "$id": "2828",
    "$values": [
    {
        "$id": "2829"
    },
    {
        "$id": "2830"
    },
    {
        "$id": "2831"
    },
    ...

and

{
    "$id": "2827"
}

respectively. It looks like it's returning a sequence number of a serialized object or something. After some Googling I came across the JsonObject attribute which, by adding it to my base class, made the objects get serialized in some sort of fashion. Mind the "some sort of fashion".

The response for a basic get looks a bit like this:

{
"$id": "2",
"$values": [
    {
        "$id": "3",
        "name": "Beigem",
        "zipCode": "1852",
        "id": "e4477c67-894e-492c-95de-001dc73730a1",
        "concurrencyStamp": "AAAAAAAAZxE=",
        "created": "2017-11-06T08:22:19.9733333",
        "createdBy": null,
        "modified": "2017-11-06T08:22:19.9733333",
        "modifiedBy": null,
        "isNew": false,
        "__Key": "e4477c67-894e-492c-95de-001dc73730a1"
    },
    ...

Still with the $id and $values things. I don't want that. I want it to be a clean json result, not the pear-shaped one like this.

  1. Why do I need to add the JsonObject attribute? I don't see it in any other example.
  2. What's up with the weird formatting. I cannot find any reference to that either...

Upvotes: 1

Views: 932

Answers (1)

CodeFuller
CodeFuller

Reputation: 31282

As a rule you should not serialize EF entities.

Consider defining data contracts for your controllers and return only data that is required by design of API call. With such approach you'll get EF entity from your repository and copy relevant fields to output data object:

// GET: api/Cities/5
[HttpGet("{id}", Name = "GetCity")]
public IActionResult Get(Guid id)
{
    City city = _cityRepository.Get(id);
    if (city == null)
    {
        return NotFound();
    }

    CityData cityData = new CityData
    {
        Name = city.Name,
        ...
    };

    return Json(cityData);
}

Upvotes: 3

Related Questions