3

I'm creating a WebAPI to do CRUD actions on entities. For my entities, in some endpoints, I don't return all of its properties for the sake of bandwidth and performance on my front end.

To achieve this I use a [JsonIgnore] attribute on my Entity class, and when I want the entire class's info to be returned I use a custom ContractResolver.

Here's an exemple of a class: (baseEntity simply has an id field)

public class Product : BaseEntity
    {
        public string Label { get; set; }
        [JsonIgnore]
        public string Color { get; set; }
        public float Price { get; set; }
        [JsonIgnore]
        public string Description { get; set; }

    }

and here's an example of the endpoint that causes me problems:

        [Route("add")]
        [HttpPost]
        public IActionResult Add([FromBody] T paramEntity)
        {
            if (_entityService.Add(paramEntity))
            {
                return Content(convertObjectToJson(paramEntity), jsonContentType);
            }
            else
            {
                return StatusCode(500);
            }
        }

where T is Product

The problem here is that the JsonIgnore attributes are applied, so if I try to POST a request with values in Description for instance, that field is totally ignored.

I found a workaround by making two Entity classes:

  • ProductParent has no JsonIgnore attributes and has all the initial properties of Product;
  • Product still has them as seen above;
  • Product inherits from ProductParent;
  • ProductParent is what is used as the parameter type for my POST request, as seen below, where U is ProductParent:
[Route("add")]
[HttpPost]
public IActionResult Add([FromBody] U paramEntity)
{
    T entityToAdd = JsonConvert.DeserializeObject<T>(JsonConvert.SerializeObject(paramEntity));
    var a = 1;
    if (_entityService.Add(entityToAdd))
    {
        return Content(convertObjectToJson(entityToAdd), jsonContentType);
    }
    else
    {
        return StatusCode(500);
    }
}

So while this kind of works it's unclean and could potentially stop working as soon as I move on to more complex types. Is there another way to achieve this?

Grumbunks
  • 1,027
  • 1
  • 7
  • 21
  • Look in to [DTO objects and AutoMapper](https://duckduckgo.com/?q=dto+objects+and+automapper). You're almost there already. I always called `Deserialize(Serialize(object))` a "poor-man's" automapper. Might as well go all in and do it the right way if you are going to use this pattern over and over. – Andy Apr 25 '21 at 04:57
  • Looks to be a duplicate of [Can I optionally turn off the JsonIgnore attribute at runtime?](https://stackoverflow.com/q/37371786/3744182) and [Ignore `[JsonIgnore]` Attribute on Serialization / Deserialization](https://stackoverflow.com/q/37954376/3744182), agree? DTOs + Automapper is also a valid solution. – dbc Apr 25 '21 at 14:33

0 Answers0