【问题标题】:Return Object Based on Query Strings根据查询字符串返回对象
【发布时间】:2017-11-11 19:19:24
【问题描述】:

我正在尝试根据查询字符串返回对象。
例如,我希望 api/users/{id}?fields=username,email,reputation 返回一个 User 类型的对象,该对象仅包含三个包含的属性(用户名、电子邮件、信誉)。

附带说明,默认情况下,在 .NET Core 中无法使用逗号分隔的查询字符串。
Here's a tutorial on making that work。

按照上面的指南,我有一个字符串列表。如何创建仅包含与这些字符串名称匹配的属性的对象?
只需几个字符串,我就可以做到这一点(感谢 Ben Hall):

List<string> listOfStrings ...; // Strings from query
User user = GetUser(id); // User from db 

User newUser = new User();

if (listOfStrings.Contains("username"))
    newUser.username = user.username;
if (listOfStrings.Contains("email"))
    newUser.email = user.email;
if (listOfStrings.Contains("reputation"))
    newUser.reputation = user.reputation;

但是对于一长串字符串(我的用户类有 30 多个属性),我该怎么做呢?

供参考,Facebook Graph API 这样做。

【问题讨论】:

  • 您可以对typeof(user) 的公共属性使用反射,并且仅将那些已命名的字段从user 复制到newUser,但是...为什么?对于 asp.net,根本不显示不在查询字符串中的 user 中的任何内容...
  • 你可以只返回一个具有这些属性的匿名对象。
  • 我在 if 语句放置 lol 上犯了一个错误

标签: c# asp.net reflection .net-core


【解决方案1】:
List<string> listOfStrings ...; // Strings from query
User user = GetUser(id); // User from db 

User newUser = new User();
//gettting object type
var userType = user.GetType();

这个解决方案需要一些关于反射的知识
它使用方法 GetValue 和 SetValue
(代码在 Visual Studio 中测试)
现在 foreach 元素在 listOfStrings

foreach(var propertyName in listOfString){
// This line of code retrives the value of the propety in the user class
 var retrivedValue = userType.GetProperty(propertyName).GetValue(user);
// This line of code sets the value retrived to the property in the newUser class
 userType.GetProperty(propertyName).SetValue(newUser, retrivedValue , null);
}

【讨论】:

  • 这行得通,谢谢。尽管我的目标是匿名返回 newUser 对象(仅包括查询中给出的属性)。这可能吗?
  • 基本上我想做 Facebook Graph API 所做的事情。返回的 JSON 对象应该只包含查询中指定的字段。
  • 我通过创建一个IDictionary&lt;string, object&gt;,在foreach 中检查null 并存储为propertyName 键和retreivedValue 值来实现这一点。然后我返回只包含给定属性且不为空的字典。这并没有使用您上面编写的所有代码,但仍然值得学习。再次感谢您的帮助:)
  • 另一种方法是使用 Json.net NullValueHandling-Enumeration 从对象返回非空值。
  • 哦,太好了!谢谢。 AutoMapper 也有空值处理 :)
【解决方案2】:

我们可以探索其他方式,例如反射,但 if 仍然可以很好地为您服务。看起来您在尝试在对象初始化程序中使用 If 时犯了一个简单的错误。在实例化新的 User 对象后,您必须这样做,例如

User newUser = new User();
if (listOfStrings.Contains("username"))
{
       newUser.username = user.username;
}

【讨论】:

【解决方案3】:

Turns out there is actually Middleware for this called Popcorn.

Popcorn 是 RESTful API 之上的一种通信协议,允许请求客户端在检索资源或资源集合时识别要包含的资源的各个字段。

它允许递归选择字段,允许多次调用 被浓缩成一个。

特点:

  • 来自 RESTful API 的选择性包含
  • 可配置的响应默认值
  • 响应排序
  • 响应值的选择性授权和许可
  • 可配置的响应检查器
  • 工厂和高级投影支持
  • 为您的 API 设置相关上下文
  • 响应对象的盲扩展

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多