【问题标题】:Conditional Anonymous type条件匿名类型
【发布时间】:2014-08-21 06:33:43
【问题描述】:

我正在开发 Web API 并使用匿名类型将 JSON 作为输出。我陷入了以下情况:

  • 如果没有可用的记录 (VALUE),那么我不想显示该 KEY。意思是,Key 应该仅在且仅在有值时才出现。

下面是我正在创建的 JSON 对象 -

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

这里周二我们确实有记录,因此它显示,但稍后对于 WE、TH、FR、SA 没有记录,因此我不想显示它们,所以我的结果将仅是 MO/TU。

我正在使用以下代码:

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() }
                    )
                }),

这样做的主要原因是减少移动设备将使用的 JSON 大小。 请帮我解决这个问题。

【问题讨论】:

    标签: json linq c#-4.0 asp.net-web-api anonymous-types


    【解决方案1】:

    匿名类型的属性在编译时是固定的——你不能让它们有条件。但是,您可能需要考虑其他一些方法:

    • 如果属性值为 null,您可以调查其是否仍包含在 JSON 表示中。如果不是,您可以添加一个扩展方法 NullIfEmpty(),如果其输入为空,则返回 null。
    • 您可以先尝试在代码中从匿名类型执行 JSON 转换,然后删除所有结果为空的属性,然后从 API 返回该 JSON 对象。 (我自己并不了解 Web API,但一定有一种方式可以说“这是一个 JSON 对象 - 向它询问它的字符串表示形式”,而不是使用匿名类型。)
    • 您可以完全放弃匿名类型,并以编程方式构建 JSON 表示,只设置您想要的属性。

    any 方法中,我强烈建议您提取一种通用方法来根据一周中的某一天得出属性值,这样您就可以:

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

    没有理由让所有代码重复 7 次。事实上,我可能会在做任何其他事情之前重构这部分 - 它会让实验变得更容易。

    【讨论】:

    • 您好 Jon Skeet,非常感谢。这是一个很大的帮助。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多