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

本文关键字:参数 最佳 枚举 Web API | 更新日期: 2023-09-27 18:09:44

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

场景1:直接枚举参数

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

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

对于这种情况,我的问题是,我是否应该在对API的请求中使用?ruleType=EmailAddress(它会自动将该值绑定到API方法中的RuleType属性(?如果是,如何最好地验证发送的RuleType参数是有效的RuleType枚举值?

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

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

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

这是枚举:

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

这里的最佳实践是什么?我在研究逐位枚举,所以在API请求中发送一个值,这导致了fields的任何组合,但不知道这是否适用于Web API,或者是否通常有更好的方法来实现这一点?

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

最简单的答案是,"没关系"。

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

public IHttpActionResult Foo(RuleType ruleType)

在WebAPI中,It Just Works-无论客户端请求URL将参数值指定为?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响应。

使URI"可读"是一种最佳实践。所以我也能理解为什么使用Enum作为字符串。但正如赫里斯托科列夫所说,你必须写一个自定义的模型活页夹。

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

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

对于场景2,C#中内置了对使用[Flags]属性的枚举中的Bitmask操作的支持

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

这在SO post 中有描述

正如Christian在回答中所说,在RESTneneneba API中使用它可能不是一个好的做法,但它应该有效。

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

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

In。Net Core,您可以在StartUp.cs或Program.cs中的ConfigureServices((方法中添加以下语句,这些语句将挂起在的哪个版本上。NET Core。

services.AddControllers()
    .AddJsonOptions(opt=> { opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); });