wake-up-neo.com

Bewährte Methode zum Übergeben von Enum-Parametern in der Web-API

Ich habe ein RESTful-Web-API-Projekt und zwei unterschiedliche Enum-Szenarien, deren beste Vorgehensweise mir nicht ganz klar ist.

Szenario 1: Unkompliziertes Enum-Parameter

Meine API-Methode erfordert einen Parameter mit dem Namen ruleType, wobei gültige Werte EmailAddress und IPAddress..__ sind. Mein Enum innerhalb des Web-API-Projekts sieht folgendermaßen aus:

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

Meine Frage für dieses Szenario lautet: Soll ich ?ruleType=EmailAddress in meiner Anfrage an die API verwenden (die diesen Wert automatisch an meine RuleType-Eigenschaft innerhalb der API-Methode bindet)? Wenn ja, wie lässt sich am besten überprüfen, ob der gesendete Parameter RuleType ein gültiger RuleType-Enum-Wert ist?

Szenario 2: Mehrere Aufzählungswerte für einen einzelnen Parameter

Meine API-Methode hat einen optionalen Parameter fields, mit dem Sie zusätzliche Daten angeben können, die zurückgegeben werden sollen. Z.B. &fields=ruleOwner,rule. Dies würde diese 2 zusätzlichen Datenbits in der Antwort zurückgeben.

Ich habe ein Enum im Web-API-Projekt, das sich auf jede mögliche field bezieht, die angefordert werden kann. Zur Zeit spalte ich die durch Kommas getrennten Felder param auf und durchläuft dann jede Zeichenfolgendarstellung dieses Enums. Daraus ergibt sich eine Liste von Enum-Werten, die ich in meiner API zum Abrufen der relevanten Daten verwenden kann.

Dies ist das Enum:

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

Was wäre die beste Praxis hier? Ich habe mir bitweise Enummen angesehen, daher wird in der API-Anfrage ein einzelner Wert gesendet, der zu einer beliebigen Kombination von fields führte, aber nicht wusste, ob dies mit einer Web-API gut funktionieren würde, oder ob es in der Regel einen besseren Weg gibt ?

13
marcusstarnes

es ist eine bewährte Methode, den URI "lesbar" zu machen. So kann ich auch verstehen, warum Sie Enum als String verwenden. Aber wie HristoKolev sagte, müssen Sie eine benutzerdefinierte Modellbinder schreiben. 

Ich denke, in Bereichen sollte man keine Kombination von Enummen verwenden. weil es schwer zu verstehen ist. Vielleicht können Sie eine Kombination aus Enum als Enum-Eintrag erstellen 

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

Die einfachste Antwort lautet: "Es spielt keine Rolle". 

Wenn der Parameter in Ihrer Controller-Methode vom Aufzählungstyp ist

public IHttpActionResult Foo(RuleType ruleType)

In WebAPI funktioniert It Just Works - unabhängig davon, ob die Clientanforderungs-URL den Parameterwert als ?ruleType=1 oder ?ruleType=EmailAddress angibt.

Wenn der Client einen Wert angibt, der für die Aufzählung nicht gültig ist, wird eine Ausnahme ausgelöst (The parameters dictionary contains a null entry for parameter 'ruleType' of non-nullable type 'RuleType' for method 'Foo' ... und der Client erhält eine 400 Bad Request-Antwort.

8
Mr. T

Für Szenario 2 ist in C # die Unterstützung für Bitmaskenoperationen in Enums mit dem Attribut [Flags] integriert 

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

Welches wird in this SO post beschrieben

Wie Christian bereits in seiner Antwort dargelegt hat, ist es wahrscheinlich keine gute Praxis, dies in einer REST - API zu verwenden, aber es sollte funktionieren.

2
Chris W

Mehrere Werte oder nicht. Wenn Sie ein Enum als Zeichenfolge verwenden, müssen Sie es manuell analysieren. In .NET sind die Enumer Ganzzahlen. Wenn Sie also ein Enum an den Standardmodellbinder senden möchten, müssen Sie Folgendes tun: ?ruleType=1.

Sie können Ihren eigenen Musterordner schreiben, der Zeichenfolgen akzeptiert, aber Sie müssen sich fragen, warum wir das tun. Wenn Sie möchten, dass der Benutzer die URL leicht identifizieren kann, verwenden Sie Zeichenfolgen. Wenn nicht, gibt es keinen Grund, keine ganzen Zahlen zu verwenden. Wie Sie gesagt haben, können Sie FlagsAttribute verwenden, um mehrere Werte zu kombinieren.

0
Hristo Kolev