C# ASP.NET核心Web API-如何处理;空";vs.“;“未定义”;在URL查询字符串中?

C# ASP.NET核心Web API-如何处理;空";vs.“;“未定义”;在URL查询字符串中?,c#,asp.net,rest,asp.net-core,asp.net-web-api,C#,Asp.net,Rest,Asp.net Core,Asp.net Web Api,我正在使用ASP.NET核心Web API(v3.1)实现REST API。目前,我不知道当通过URL中的查询字符串传递时,如何区分“未定义”值和“空”值 例如,假设API管理用户,所有用户都有一个名字和一个姓氏。此外,所有用户可能都有一个中间名 REST API允许查询这些用户,如下所示: GET api/user?lastName=doe (这将返回姓为“Doe”的用户资源集合)。相关的控制器类可以如下所示: [HttpGet] public IActionResult GetUsers(

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

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

REST API允许查询这些用户,如下所示:

GET api/user?lastName=doe
(这将返回姓为“Doe”的用户资源集合)。相关的控制器类可以如下所示:

[HttpGet]
public IActionResult GetUsers(字符串firstName、字符串lastName、字符串middleName)
{
//在数据库中搜索用户
//忽略firstName和middleName,因为它们为空
}
当查询包含中间名时,我的问题出现了:

GET api/user?middleName=null&firstName=john
此查询(其中
middleName
显式设置为
null
)应返回名为“John”且没有中间名的用户。与此相反,请求

GET api/user?firstName=john
(其中
middleName
undefined
)应返回名为“John”的所有用户,无论他们是否有中间名

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

编辑:

我的例子是误导性的,并不像我预期的那样,因为

GET api/user?middleName=null&firstName=john
middleName
设置为字符串值
“null”
,而不是
null
(如无)


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

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

正如其他人已经注意到的,这里,
middleName=null
意味着您正在将
middleName
设置为“null”,而不是
null
,因为它是一个字符串变为一个字符串。如果要允许此约定,需要执行以下操作:

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

这仍然不包括如何确定是否显式设置。默认情况下,所有操作参数都是可选的。在这里,最好是显式检查查询中是否存在该值:

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

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

在查询
api/user?middleName=null&firstName=john
中,
null
是一个字符串。所以,
middleName
不是空的,它有一个值,值是
null
@T–你是说
“null”
?是的。我只是在我的本地主机上尝试一下。你是对的,在
api/user?middleName=null&firstName=john
中,
middleName
的值是
“null”
。因此,在我的控制器中,我是否应该将C#
null
视为“未定义”,将特定字符串(如
“null”
)或URLEncoded NUL值(%00)(如建议的)视为C#
null
。这被认为是常见的还是良好的做法?如果我孩子的中间名是“空”怎么办?谢谢你的回答和大家的评论。我现在决定结合使用
Request.Query.ContainsKey()
和一个特定的字符串,如url编码的空字符串(
%00
),以便能够筛选空值并决定是否包含筛选器。因此,您应该能够给您的孩子“null”作为中间名(但不是
%00
),并通过api进行搜索;)我以前通过在值上支持(可选)前缀来实现这一点/api/user?firstName=sue&middleName=isnull:true&lastName=eq:doe编写一个方法,将可选前缀剥离到具有所需运算符和值的结构中,非常容易。我在我们的Csg.ListQuery库中针对这种类型的API的更高级的解决方案中做了类似的事情,它为这种类型的API调用(事物列表)提供了标准化的请求/响应。在
param1=¶m2=foo
示例中,模型绑定器将param1解释为
null
。这是我自己试过的。