【问题标题】:Filtering Out Properties in an ASP.NET Core API过滤掉 ASP.NET Core API 中的属性
【发布时间】:2016-04-02 06:27:00
【问题描述】:

我想在我的 API 中提供以下 JSON:

{
  "id": 1
  "name": "Muhammad Rehan Saeed",
  "phone": "123456789",
  "address": {
    "address": "Main Street",
    "postCode": "AB1 2CD"
  }
}

我想让客户端能够过滤掉他们不感兴趣的属性。以便以下 URL 返回 JSON 的子集:

`/api/contact/1?include=name,address.postcode

{
  "name": "Muhammad Rehan Saeed",
  "address": {
    "postCode": "AB1 2CD"
  }
}

在 ASP.NET Core 中实现此功能的最佳方法是:

  1. 该解决方案可以全局应用,也可以应用于单个控制器或过滤器等操作。
  2. 如果解决方案使用反射,那么还必须有一种方法来优化特定控制器操作,方法是提供一些代码以出于性能原因手动过滤出属性。
  3. 它应该支持 JSON,但支持 XML 等其他序列化格式会很好。

我找到了使用自定义 JSON.Net ContractResolverthis 解决方案。可以通过将合约解析器添加到 ASP.Net Core 使用的默认合约解析器或手动添加到像 this 代码示例这样的单个操作而不是控制器来全局应用合约解析器。此外,这是一个 JSON 特定的实现。

【问题讨论】:

标签: asp.net json json.net asp.net-core asp.net-core-1.0


【解决方案1】:

您可以使用dynamicExpandoObject 来创建包含您需要的属性的动态对象。 ExpandoObjectdynamic 关键字在后台使用的,它允许在运行时动态添加和删除属性/方法。

[HttpGet("test")]
public IActionResult Test()
{
    dynamic person = new System.Dynamic.ExpandoObject();

    var personDictionary = (IDictionary<string, object>)person;
    personDictionary.Add("Name", "Muhammad Rehan Saeed");

    dynamic address = new System.Dynamic.ExpandoObject();
    var addressDictionary = (IDictionary<string, object>)address;
    addressDictionary.Add("PostCode", "AB1 2CD");

    personDictionary.Add("Address", address);

    return Json(person);
}

这会导致

{"Name":"Muhammad Rehan Saeed","Address":{"PostCode":"AB1 2CD"}}

您只需要创建一个服务/转换器或类似的东西,它们将使用反射来循环您的输入类型,并且只保留您指定的属性。

【讨论】:

  • 正如您的示例中所示,来自动态的属性被序列化为 PascalCasing(或“原样”),而来自普通类的属性在 .NET Core 中默认序列化为 camelCasing。知道如何制作动态属性 camelCasing 吗?
  • @NielsBrinch: 抱歉之前没看到评论,但是 dynamic 在底层只使用了一个 ExpandoObject,它是一个 IDictionary&lt;string,object&gt;,所以在序列化它时,你有效地序列化了一个字典到 JSON 对象中
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-02
相关资源
最近更新 更多