.net - Minify Your Dto In Web Api

Viewed 98

Imagine if you have a dto that includes many properties that are applicable to the business logic. A simple example would be the following:

public class PartnerDto
    {
        public int PartnerId { get; set; }
        public int BrandId { get; set; }
        public int CobrandIdId { get; set; }
        public Brand brand { get; set; }
    }

In this example the Brand class onto itself has custom properties.

This is great, except when I like the WebApi to consume this class either in the response body, or as a request payload. But what if the client doesn't care about the custom properties? Let's say the client only cares about the int fields in this case.

One idea was to create a MiniPartnerDto that only includes the properties I like to expose to the client. Then, use AutoMapper to map the two objects. Essentially the following:

public class MiniPartnerDto
    {
        public int PartnerId { get; set; }
        public int BrandId { get; set; }
        public int CobrandIdId { get; set; }
    }

[HttpGet("{id}")]
        public async Task<IActionResult> Get(int id)
        {
            var result = _mapper.Map<MiniPartnerDto>(await _partnerManager.GetById(id));
            if (result == null)
            {
                return NotFound();
            }
            return Ok(result);
        } 

I don't mind this idea, but I don't love it. I was wondering if there is a way for me to ignore certain properties without having the need to create a completely different class.

1 Answers

If you don't want to make more object values ,one of the ways is conditional property serialization in Json.NET.

Try it like this:

public class PartnerDto
{
    public int PartnerId { get; set; }
    public int BrandId { get; set; }
    public int CobrandIdId { get; set; }
    public Brand Brand { get; set; }

    public bool ShouldSerializeBrand()
    {
        // Brand property serialized only when brand name is Stackoverflow
        return (Brand.Name == "Stackoverflow");
    }
}

In Complex cases you can handle it by enum like this:

public enum SLForPartnerDto
{
    None,
    ViewForm,
    EditForm
}

public class PartnerDto
{
    [JsonIgnore]
    public SLForPartnerDto SerializationLevel { get; set; }
    public int PartnerId { get; set; }
    public int BrandId { get; set; }
    public int CobrandIdId { get; set; }
    public Brand Brand { get; set; }

    public bool ShouldSerializePartnerId()
    {
        return (SerializationLevel != SLForPartnerDto.None);
    }
    public bool ShouldSerializeBrand()
    {
        return (SerializationLevel == SLForPartnerDto.ViewForm);
    }
}

Now you need just set SerializationLevel in model like:

var model = new PartnerDto();
model.SerializationLevel = SLForPartnerDto.ViewForm;

But I think it is not best practice.

Related