ASP.NET Core Web API - 如何处理 URL 查询字符串中的“null”与“undefined”?

Posted

技术标签:

【中文标题】ASP.NET Core Web API - 如何处理 URL 查询字符串中的“null”与“undefined”?【英文标题】:ASP.NET Core Web API - How to handle "null" vs. "undefined" in URL query strings? 【发布时间】:2020-07-13 00:35:04 【问题描述】:

我正在使用 ASP.NET Core Web API (v3.1) 实现 REST API。目前,当通过 URL 中的查询字符串传递时,我不确定如何区分“未定义”值和“空”值。

例如,假设 API 管理用户,所有用户都有名字和姓氏。此外,所有用户都可能有一个中间名。

REST API 允许像这样查询这些用户:

GET api/user?lastName=doe

(这将返回姓氏“Doe”的用户资源集合)。相关的控制器类可能如下所示:

[HttpGet]
public IActionResult GetUsers(string firstName, string lastName, string middleName)

    // Search database for users
    // Ignore firstName and middleName, because they are null

当查询包含中间名时,我的问题出现了:

GET api/user?middleName=null&firstName=john

此查询(其中middleName 明确设置为null)应返回名字为“John”且没有中间名的用户。对比请求

GET api/user?firstName=john

(其中middleNameundefined)应该返回所有名字为“John”的用户,无论他们是否有中间名。

在这两种情况下,我的控制器方法中的middleName 参数都设置为null。如何区分控制器中的这些查询?

编辑:

我的示例具有误导性,并且表现不如我预期,因为

GET api/user?middleName=null&firstName=john

middleName 设置为字符串值"null" 而不是null(就像什么都没有)。

我仍然想让客户端搜索没有中间名的用户(中间名的数据库值为 NULL)。这如何通过 URL 传递并由控制器进一步处理?

【问题讨论】:

在查询api/user?middleName=null&firstName=john中,null是一个字符串。所以,middleName 不为空,它有一个值,而该值为null @Tân 你的意思是"null" 是的。我只是在我的本地主机上尝试一下。 你是对的,在api/user?middleName=null&firstName=johnmiddleName 的值是"null"。因此,在我的控制器内部,我是否应该将 C# null 视为“未定义”,将特定字符串(如 "null")或 URLEncoded NUL 值 (%00)(如建议的 here)视为 C# null。这被认为是常见做法还是良好做法? 如果我孩子的中间名是“null”怎么办? 【参考方案1】:

一般来说,当来自请求时,没有固有的方法来区分 null 和 undefined,因为它们本质上是相同的。所有值最初都是字符串,然后由模型绑定器强制转换为它们的实际类型。

正如其他人已经指出的那样,这里的middleName=null 表示您将middleName 设置为“null”,不是 null,因为它是一个字符串进入一个字符串。如果您想允许这种约定,您需要执行以下操作:

if (middleName == "null")
    middleName = null;

但是,在查询字符串中指定 null 的真正方法是提供不带值的键,例如param1=&param2=foo。在这里,param1 没有任何价值。尽管如此,模型绑定器仍会将其解释为 "",而不是 null。您当然可以执行与上述相同的操作,检查此条件并将其显式设置为 null,或者仅使用 string.IsNullOrEmpty 作为值的测试。

这仍然没有涵盖如何确定它是否被显式设置。默认情况下,所有操作参数都是可选的。您可以在这里做的最好的事情是明确检查查询中是否存在该值:

if (Request.Query.ContainsKey("middleName"))
    // explicitly passed

然后,您可以根据该值是否实际存在于查询中来决定如何处理该值。

【讨论】:

感谢您的回答以及其他所有人的 cmets。我现在决定使用 Request.Query.ContainsKey() 和特定字符串(如 url 编码的 NULL 字符串 (%00) 的组合,以便能够过滤空值并决定是否包含过滤器。所以你应该能够给你的孩子“null”作为中间名(但不是%00)并通过api搜索它;) 我以前通过在值上支持(可选)前缀来做到这一点。 /api/user?firstName=sue&middleName=isnull:true&lastName=eq:doe 编写一个将可选前缀剥离到具有所需运算符和值的结构中的方法非常容易。我在 Csg.ListQuery 库中针对此类 API 的更高级解决方案中做了类似的事情,它为此类 API 调用(事物列表)提供了标准化的请求/响应。 github.com/csgsolutions/Csg.ListQuery/blob/master/src/… param1=&param2=fooexample 中,param1 将被模型绑定器解释为null。这是我自己尝试过的。

以上是关于ASP.NET Core Web API - 如何处理 URL 查询字符串中的“null”与“undefined”?的主要内容,如果未能解决你的问题,请参考以下文章

带有 EF Core 更新实体的 ASP.Net 核心 Web Api 如何

如何在 ASP.NET Core Web API 中发布对象列表

Asp.Net Core Web API 应用程序:如何更改监听地址?

ASP.Net Core Web API 如何返回 File。

如何使 ASP.NET Core Web API 操作异步执行?

如何注销或过期 ASP.NET Core Web API 的 JWT 令牌?