问题 在Web API中传递枚举参数的最佳实践


我有一个RESTful Web API项目,我有两个不同的Enum场景,我不确定是最佳实践。

场景1:直截了当的Enum Param

我的API方法需要一个名为的参数 ruleType,有效值 EmailAddress 和 IPAddress。 我在Web API项目中的枚举如下所示:

public enum RuleType
{
    None = 0,
    EmailAddress = 1,
    IPAddress = 2
}

我对这个场景的问题是,我应该使用 ?ruleType=EmailAddress 在我对API的请求中(自动将该值绑定到我的 RuleType API方法中的属性)?如果是这样,如何最好地验证 RuleType param发送,是一个有效的RuleType枚举值?

场景2:单个参数的多个枚举值

我的API方法有一个可选的 fields param,它允许您指定应返回的任何其他数据。例如。 &fields=ruleOwner,rule。这将在响应中返回那2个额外的数据位。

我在Web API项目中有一个枚举,它与每个可能的内容相关 field 可能是请求的,目前,我正在拆分逗号分隔的字段param,然后循环遍历该枚举的每个字符串表示,将其解析为等效的枚举,得到一个Enum值列表,然后我可以在我的API中使用检索相关数据。

这是Enum:

public enum OptionalField
{
    None = 0,
    RuleOwner = 1,
    Rule = 2,
    etc.
}

这里最好的做法是什么?我正在研究按位枚举,因此在API请求中发送了一个值,这导致了任何组合 fields 但不知道这是否适用于Web API,或者是否通常有更好的方法来解决这个问题?


8708
2017-09-30 10:51


起源



答案:


将URI设置为“人类可读”是最佳做法。所以我也可以理解你为什么使用Enum作为字符串。但正如HristoKolev所说,你必须写一个自定义的Model Binder。

在字段中我认为你不应该使用枚举的组合。因为很难理解。也许你可以创建enum作为枚举条目的组合

public enum OptionalField
{
    None = 0,
    RuleOwner = 1,
    Rule = 2,
    RuleAndRuleOwner = 3,
    etc.
}

2
2017-10-01 06:42





最简单的答案是“无所谓”。

如果控制器方法中的参数是枚举类型

public IHttpActionResult Foo(RuleType ruleType)

在WebAPI中, 它只是工作  - 无论客户端请求URL是否将parmeter值指定为 ?ruleType=1 要么 ?ruleType=EmailAddress

如果客户端指定对枚举无效的值,则抛出异常(The parameters dictionary contains a null entry for parameter 'ruleType' of non-nullable type 'RuleType' for method 'Foo' ... 并且客户得到了 400 Bad Request 响应。


6
2018-01-27 21:38



我喜欢那些与ASP.NET Core相关的东西 它只是工作 答案^ _ ^ - WoIIe


答案:


将URI设置为“人类可读”是最佳做法。所以我也可以理解你为什么使用Enum作为字符串。但正如HristoKolev所说,你必须写一个自定义的Model Binder。

在字段中我认为你不应该使用枚举的组合。因为很难理解。也许你可以创建enum作为枚举条目的组合

public enum OptionalField
{
    None = 0,
    RuleOwner = 1,
    Rule = 2,
    RuleAndRuleOwner = 3,
    etc.
}

2
2017-10-01 06:42





最简单的答案是“无所谓”。

如果控制器方法中的参数是枚举类型

public IHttpActionResult Foo(RuleType ruleType)

在WebAPI中, 它只是工作  - 无论客户端请求URL是否将parmeter值指定为 ?ruleType=1 要么 ?ruleType=EmailAddress

如果客户端指定对枚举无效的值,则抛出异常(The parameters dictionary contains a null entry for parameter 'ruleType' of non-nullable type 'RuleType' for method 'Foo' ... 并且客户得到了 400 Bad Request 响应。


6
2018-01-27 21:38



我喜欢那些与ASP.NET Core相关的东西 它只是工作 答案^ _ ^ - WoIIe


对于场景2,使用[Flags]属性在Enum中内置了对Enums中的位掩码操作的支持

[Flags]
public enum OptionalField
{
    None = 0,
    RuleOwner = 1,
    Rule = 2,
    RuleAdministrator = 4,
    RuleEditor = 8,
    ...etc
}

其中描述了 这个SO帖子

基督教 在他的回答中已经说过,在REST API中使用它可能不是一个好习惯,但它应该可行。


2
2018-02-03 20:07





是否有多个值,如果您使用Enum作为字符串,则必须手动解析它。在.NET中,Enums是整数,所以如果你想将枚举发送到默认的模型绑定器,你必须这样做: ?ruleType=1

你可以编写自己的模型绑定器来接受字符串,但你必须问问自己为什么要这样做?如果您希望用户能够轻松识别URL,请使用字符串。如果没有,没有理由不使用整数。如您所说,您可以使用FlagsAttribute组合多个值。


0
2017-09-30 11:11



但是有一个很好的理由使用字符串而不是数字:数字是内部实现细节,而API是应用程序的公共前端。有正当理由要重新排序成员 enum,但默认情况下这样做会更改数值 - 但不会更改名称。在代码内部,数值不应该有所不同,因为一切都引用相同的 enum 定义。外部调用者没有获得这种好处,应该使用字符串形式来确保服务代码更新的一致性。 - Jonathan Gilbert
是的,但如果使用字符串,则无法轻松发送复合值([Flags])。可以通过手动设置整数来修复排序问题。 - Hristo Kolev