【问题标题】:How to exclude a property in WebAPI on demand如何按需排除 WebAPI 中的属性
【发布时间】:2014-05-06 17:11:10
【问题描述】:

我是 WebApi 的新手,所以如果这个问题是业余的,请原谅:我使用 AngularJS 的“$resource”与 WebApi-Controller“BondController”进行通信。这很好用。 我的问题:实体“债券”引用了实体“价格”列表:

public class Bond
{
    public int ID { get; set; }
    ...
    public virtual List<Price> Prices { get; set; }
}

我正在寻找一种排除嵌套列表“价格”的方法,例如

[JsonIgnore]

但是,在某些其他情况下,我仍然需要一种方法来检索包含此嵌套列表的债券,例如通过第二个控制器“Bond2”。

我能做什么?

我需要在实体 Bond 之上添加一些 ViewModel 吗? 我可以以某种方式排除控制器本身的价格列表吗:

public IQueryable<Bond> GetBonds()
{
     return db.Bonds [ + *some Linq-Magic that excludes the list of Prices*]
}

背景:价格列表可能会变得相当长,Get-Requests 很容易变得 > 1MB。在大多数情况下,价格甚至不需要向用户显示,所以我想将它们从响应中排除。但在一种情况下,他们确实...感谢您的意见!

编辑: 我看到,对于某种 Linq Magic,我需要一种新类型“PricelessBond”

EDIT2 找到了一个使用 DTO here 的好例子,并将使用它。

解决方案是创建一个非持久性 BondDTO 类,该类充当“外壳”,并且仅具有您希望在特定用例中可见的那些属性,然后在 BondDTOController 中转换 BondDTO 的选择=> BondDTO 通过 Linq Lambda Select 表达式。

【问题讨论】:

    标签: c# linq asp.net-web-api


    【解决方案1】:

    我不是 WebApi 方面的专家,但您的问题似乎不止一个。 为什么不创建类层次结构?

    public class PricelessBond // :)
    {
        public int ID {get; set;}
    }
    
    public class Bond : PricelessBond
    {
        public List<Price> Prices {get; set;}
    }
    

    然后您可以通过两种不同的方法公开数据:

    public class BondsController : ApiController
    {
        [Route("api/bonds/get-bond-without-price/{id}")]
        public PricelessBond GetBondWithoutPrice(int id)
        {
            return DataAccess.GetBondWithoutPrice(id);
        }
    
        [Route("api/bonds/get-bond/{id}")]
        public Bond GetBond()
        {
            return DataAccess.GetBond(id);
        }
    }
    

    在你的DataAccess 课堂上:

    public class DataAccess
    {
        public PricelessBond GetBondWithoutPrice(int id)
        {
            return db.Bonds
                .Select(b => new PricelessBond
                {
                    ID = b.ID
                })
                .Single(b => b.ID == id);
        }
    
        public Bond GetBond(int id)
        {
            return db.Bonds
                .Select(b => new Bond
                {
                    ID = b.ID,
                    Prices = b.Prices.Select(p => new Price{}).ToArray()
                })
                .Single(b => b.ID == id);
        }
    }
    

    当然,拥有两种数据访问方法意味着一些代码开销,但由于您说响应可能会超过 1MB,这也意味着您应该保留您的数据库服务器,而不是获取您不需要的数据。

    因此,在您的数据访问层中,仅加载每个操作所需的数据。

    我已经在一个临时项目中对此进行了测试,并且成功了。

    【讨论】:

    • 嗯,我理解你的想法是否正确:我应该将债券实例化为 Bond,使用两个控制器(BondController 和 PricelessBondController),当我需要 PricelessBond 时,施放?
    • 嗯,我对你的回答想得越多,我得到的就越少:o)
    • 感谢扩展!
    猜你喜欢
    • 1970-01-01
    • 2015-03-03
    • 2017-10-25
    • 1970-01-01
    • 1970-01-01
    • 2019-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多