2016-04-06 8 views
20

Gibt es eine Möglichkeit, alle Enums als String-Wert in Swagger statt ihrer int-Wert anzuzeigen?Swagger UI Web API-Dokumentation Aktuelle Enums als Zeichenfolgen?

Ich möchte in der Lage sein, POST-Aktionen zu übermitteln und Enums entsprechend ihrem String-Wert zu setzen, ohne jedes Mal auf die Enum zu schauen.

Ich versuchte DescribeAllEnumsAsStrings, aber der Server erhält dann Zeichenfolgen anstelle der Enum-Wert, die nicht das ist, was wir suchen.

Hat jemand das gelöst?

Edit:

public class Letter 
{ 
    [Required] 
    public string Content {get; set;} 

    [Required] 
    [EnumDataType(typeof(Priority))] 
    public Priority Priority {get; set;} 
} 


public class LettersController : ApiController 
{ 
    [HttpPost] 
    public IHttpActionResult SendLetter(Letter letter) 
    { 
     // Validation not passing when using DescribeEnumsAsStrings 
     if (!ModelState.IsValid) 
      return BadRequest("Not valid") 

     .. 
    } 

    // In the documentation for this request I want to see the string values of the enum before submitting: Low, Medium, High. Instead of 0, 1, 2 
    [HttpGet] 
    public IHttpActionResult GetByPriority (Priority priority) 
    { 

    } 
} 


public enum Priority 
{ 
    Low, 
    Medium, 
    High 
} 
+1

Do Sie möchten, dass das Schema den Wert als String beschreibt und dann eine ganze Zahl an den Server schreibt? JSON.net wird beide Werte gut behandeln, also ist die Integer-Version eine eindeutige Anforderung? Ich glaube nicht, dass Swagger einen Enum-Typ sowohl mit dem String- als auch dem Integer-Wert unterstützt. – Mig

+1

Ihr erwartetes Verhalten ist unklar. Können Sie besser erklären, was Swagger UI anzeigen soll und was Sie mit Beispielen an Ihre Web-API senden möchten? –

+0

Mig genau das, was ich wollte. Wenn es an meinen Server gesendet wird, weil die Validierung der Ganzzahl fehlschlägt, liegt das Problem möglicherweise in meinem Code. Aber du sagst, dass es in meiner Datenbank als Integer gespeichert wird? Oder wird es als Integer gespeichert? Wird eine Verschwendung sein, es als Zeichenkette auf meiner Datenbank zu speichern –

Antwort

59

Von the docs:

httpConfiguration 
    .EnableSwagger(c => 
     { 
      c.SingleApiVersion("v1", "A title for your API"); 

      c.DescribeAllEnumsAsStrings(); // this will do the trick 
     }); 

Auch, wenn Sie dieses Verhalten möchte nur auf eine bestimmte Art und Eigenschaft, verwenden Sie die StringEnumConverter:

public class Letter 
{ 
    [Required] 
    public string Content {get; set;} 

    [Required] 
    [EnumDataType(typeof(Priority))] 
    [JsonConverter(typeof(StringEnumConverter))] 
    public Priority Priority {get; set;} 
} 
+4

Diese Antwort sollte das Lösungshäkchen erhalten. – sprinter252

+0

dies funktioniert nicht für mich. [EnumDataType (typeof (Priorität))] [JsonConverter (typeof (StringEnumConverter))] – Lineker

+0

das ist sauber danke –

14

So Ich denke, ich habe ein ähnliches Problem. Ich suche nach Swagger, um Enums zusammen mit dem Int -> String Mapping zu erzeugen. Die API muss den Int akzeptieren. Das Swagger-Ui zählt weniger, was ich wirklich will, ist Code-Generierung mit einem "echten" Enum auf der anderen Seite (Android-Apps mit Retrofit in diesem Fall).

Aus meiner Forschung scheint dies letztlich eine Grenze der OpenAPI-Spezifikation zu sein, die Swagger verwendet. Es ist nicht möglich, Namen und Nummern für Enums anzugeben.

Das beste Problem, das ich gefunden habe, ist https://github.com/OAI/OpenAPI-Specification/issues/681, die wie ein "vielleicht bald" aussieht, aber dann müsste Swagger aktualisiert werden, und in meinem Fall auch Swashbuckle.

Vorläufig bestand meine Problemumgehung darin, einen Dokumentfilter zu implementieren, der nach Enums sucht und die relevante Beschreibung mit dem Inhalt des Enums füllt.

 GlobalConfiguration.Configuration 
      .EnableSwagger(c => 
       { 
        c.DocumentFilter<SwaggerAddEnumDescriptions>(); 

        //disable this 
        //c.DescribeAllEnumsAsStrings() 

SwaggerAddEnumDescriptions.cs:

using System; 
using System.Web.Http.Description; 
using Swashbuckle.Swagger; 
using System.Collections.Generic; 

public class SwaggerAddEnumDescriptions : IDocumentFilter 
{ 
    public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, IApiExplorer apiExplorer) 
    { 
     // add enum descriptions to result models 
     foreach (KeyValuePair<string, Schema> schemaDictionaryItem in swaggerDoc.definitions) 
     { 
      Schema schema = schemaDictionaryItem.Value; 
      foreach (KeyValuePair<string, Schema> propertyDictionaryItem in schema.properties) 
      { 
       Schema property = propertyDictionaryItem.Value; 
       IList<object> propertyEnums = [email protected]; 
       if (propertyEnums != null && propertyEnums.Count > 0) 
       { 
        property.description += DescribeEnum(propertyEnums); 
       } 
      } 
     } 

     // add enum descriptions to input parameters 
     if (swaggerDoc.paths.Count > 0) 
     { 
      foreach (PathItem pathItem in swaggerDoc.paths.Values) 
      { 
       DescribeEnumParameters(pathItem.parameters); 

       // head, patch, options, delete left out 
       List<Operation> possibleParameterisedOperations = new List<Operation> { pathItem.get, pathItem.post, pathItem.put }; 
       possibleParameterisedOperations.FindAll(x => x != null).ForEach(x => DescribeEnumParameters(x.parameters)); 
      } 
     } 
    } 

    private void DescribeEnumParameters(IList<Parameter> parameters) 
    { 
     if (parameters != null) 
     { 
      foreach (Parameter param in parameters) 
      { 
       IList<object> paramEnums = [email protected]; 
       if (paramEnums != null && paramEnums.Count > 0) 
       { 
        param.description += DescribeEnum(paramEnums); 
       } 
      } 
     } 
    } 

    private string DescribeEnum(IList<object> enums) 
    { 
     List<string> enumDescriptions = new List<string>(); 
     foreach (object enumOption in enums) 
     { 
      enumDescriptions.Add(string.Format("{0} = {1}", (int)enumOption, Enum.GetName(enumOption.GetType(), enumOption))); 
     } 
     return string.Join(", ", enumDescriptions.ToArray()); 
    } 

} 

Daraus ergibt sich in etwa wie folgt auf Ihre Prahlerei-ui so zumindest kann man "sehen, was du tust": enter image description here

+0

+1 Ich wollte Beschreibungen zu Enums hinzufügen (nur um "enum" zu beschreiben), dachte nie darüber nach. Ich habe bereits verschiedene Filter installiert, suchte aber nach etwas "Organischem", aber es gibt keine Unterstützung. Nun, filtert den ganzen Weg :) – NSGaga