Conditional Anonymous type

I am working on Web API and using Anonymous type to make JSON as output. I am stuck in the following scenario:

  • If there is no record(VALUE) available then i don't want to show that KEY. Meaning, Key should only appear when and only when there is value.

Below is the JSON object i am creating -

    "TU": [
{
"BLOCK": [
[
"00:00",
"00:59"
]
]
}
],
"WE": [],// empty
"TH": [],// empty
"FR": [],// empty
"SA": [] // empty

Here for Tuesday we do have records and hence its showing but later for WE,TH,FR,SA there are not records and hence i don't want to show them so my result will be MO/TU only.

I am using below code:

var result = new
        {
            CustomerID = custId,
            DeviceID = dId,
            Kind = kind,
            WebList = filter.Select(filt => new
            {
                URL = filt.FilterName,
                TimeBlockFlag = new ChicoHelper().GetFlag(browserlimit, filt.ID, filt.FilterOptionID, KindId),
                DAILY = browserlimit.Where(xx => xx.FilterID == filt.ID && xx.OptionTypeID == daily).Select(xx => xx.BlockTimeLimit).SingleOrDefault(),
                WEEKLY = browserlimit.Where(xx => xx.FilterID == filt.ID && xx.OptionTypeID == weekly).Select(xx => xx.BlockTimeLimit).SingleOrDefault(),
                MONTHLY = browserlimit.Where(xx => xx.FilterID == filt.ID && xx.OptionTypeID == monthly).Select(xx => xx.BlockTimeLimit).SingleOrDefault(),
                HASVALUES = browserlimit.Where(xx => xx.FilterID == filt.ID).Count() > 0 ? 1 : 0,
                BLOCKTYPE = new ChicoHelper().GetBlockType(browserlimit,filt.ID,filt.FilterOptionID,KindId),
                SU = blockedlimit.Where(x => x.OptionID == sunday && x.FilterID == filt.ID).GroupBy(x => new { x.BlockDay })
                               .Select(x => new
                               {

                                   BLOCK = x.Select(y =>
                                     new[] { y.BlockStartTime.MakeFormatedTime(), y.BlockEndTime.MakeFormatedTime() }
                                   )
                               }),
                MO = blockedlimit.Where(x => x.OptionID == monday && x.FilterID == filt.ID).GroupBy(x => new { x.BlockDay })
                .Select(x => new
                {
                    BLOCK = x.Select(y =>
                      new[] { y.BlockStartTime.MakeFormatedTime(), y.BlockEndTime.MakeFormatedTime() }
                    )
                }),
                TU = blockedlimit.Where(x => x.OptionID == tuesday && x.FilterID == filt.ID).GroupBy(x => new { x.BlockDay })
                               .Select(x => new
                               {
                                   BLOCK = x.Select(y =>
                                     new[] { y.BlockStartTime.MakeFormatedTime(), y.BlockEndTime.MakeFormatedTime() }
                                   )
                               }),
// if i can put some condition like if there is not record for WE then don't show it. 
                WE = blockedlimit.Where(x => x.OptionID == wednesday && x.FilterID == filt.ID).GroupBy(x => new { x.BlockDay })
                .Select(x => new
                {
                    BLOCK = x.Select(y =>
                      new[] { y.BlockStartTime.MakeFormatedTime(), y.BlockEndTime.MakeFormatedTime() }
                    )
                }),

The main reason for doing this is to reduce the JSON size which will be consumed by Mobile Devices. Please help me with this.

Jon Skeet
people
quotationmark

The properties of an anonymous type are fixed at compile-time - you can't make them conditional. However, some other approaches you might want to think about:

  • You could investigate whether a property is still included in the JSON representation if its value is null. If it's not, you could add an extension method NullIfEmpty() which returns null if its input is empty.
  • You could try performing the JSON conversion from the anonymous type in code first, then delete any properties with an empty set of results, then just return that JSON object from the API. (I don't know Web API myself, but there must be a way of saying "Here's a JSON object - ask it for its string representation" rather than using an anonymous type.)
  • You could ditch the anonymous type entirely, and build up the JSON representation programmatically, setting just the properties you want.

In any approach, I would strongly advise you to extract a common method to come up with the property value based on a day of the week, so you can have:

...
SU = blockedLimit.GetDayBlocks(sunday),
MO = blockedLimit.GetDayBlocks(monday),
TU = blockedLimit.GetDayBlocks(tuesday),
...

There's no reason to have all that code repeated 7 times. In fact, I'd probably refactor that part before doing anything else - it'll make it easier to experiment.

people

See more on this question at Stackoverflow