0

I'm working with .NET 5 and Api Controllers. In my startup class (ConfigureServices) I have the following:

services.AddControllers().AddNewtonsoftJson(x =>
            {
                x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
            });

Then I have a controller like this:

[HttpPost]
public async Task<ActionResult<Company>> PostCompany(Company company)
{
}

And Company is a class like this

public class Company : Entity
    {
        Coordinates coordinates;
        public int CompanyId { get; set; }
        public string Name { get; set; }
        public NpgsqlTypes.NpgsqlBox Bounds { get; set; }
        [NotMapped]
        public Coordinates Coordinates
        {
            get { return coordinates ?? new Coordinates(); } 
            set { coordinates = value; Bounds = new NpgsqlTypes.NpgsqlBox(coordinates.Top, coordinates.Right, coordinates.Bottom, coordinates.Left); }  
        }
    }

    public class Coordinates
    {
        public double Left { get; set; }
        public double Right { get; set; }
        public double Bottom { get; set; }
        public double Top { get; set; }
    }

From postman I send a POST with this body (Content-Type: application/json in the Headers)

{
   "companyId":0,
   "name":"company 1",
   "coordinates":{
      "left":2,
      "right":5,
      "bottom":43,
      "top":3
   }
}

name has the correct value but why coordinates in the parameter of the api controller is always 0 in all its values? Seems it's newtonsoft deserialization because if I use this

public async Task<ActionResult<Company>> PostCompany(Object company2)
{
    var jsonString = company2.ToString();
    Company company = JsonConvert.DeserializeObject<Company>(jsonString);
}

I see the coordinates values in the company2 but not when deserialized into company object (which has 0 for all the coordinates).

Any idea? Thanks in advance. Guillermo.

polonskyg
  • 4,269
  • 9
  • 41
  • 93
  • Try removing `[NotMapped]` it's probably what's causing it – zaitsman Sep 05 '21 at 04:24
  • Also, generally speaking you would never post and receive the DB model via an API, read up on DTO (Data Transfer Object) – zaitsman Sep 05 '21 at 04:25
  • In the getter for `Coordinates` you need to do `return coordinates ?? coordinates = new Coordinates();` because Json.NET never sets the value back after it is populated. For why see [this answer](https://stackoverflow.com/a/32493007/3744182) to [Why are all the collections in my POCO are null when deserializing some valid json with the .NET Newtonsoft.Json component](https://stackoverflow.com/q/32491966/3744182) which is basically the same problem, although it asks about JSON arrays rather than objects. – dbc Sep 05 '21 at 05:14
  • Alternatively, if you don't want to modify the setter in that way, that you could apply `[JsonProperty(ObjectCreationHandling = ObjectCreationHandling.Replace)]` to `public Coordinates Coordinates` which will force `Coordinates` to be freshly allocated and set back during serialization. See [How to apply ObjectCreationHandling.Replace to selected properties when deserializing JSON?](https://stackoverflow.com/a/33746313/3744182) for a similar question. – dbc Sep 05 '21 at 05:15
  • @dbc That made it work! thx! Please post it as an answer to selected as the correct one. – polonskyg Sep 06 '21 at 00:54
  • @zaitsman the [NotMapped] it's not related, it's telling it's not going to be mapped in Entity Framework, removing it, of course, didn't fix it I completely agree domain classes never should be use there and DTOs should be, but this is something done by other and consumed by clients so I cannot change the interface until they fix it on their end or start doing other thing I don't want/have the time now. – polonskyg Sep 06 '21 at 00:56

0 Answers0