2016-04-06 12 views
20

すべての列挙型をint値ではなくswaggerの文字列値として表示する方法はありますか?Swagger UI Web Apiのドキュメント現在の列挙型の列挙型ですか?

POSTアクションを送信し、毎回列挙型を参照しなくても、文字列値に基づいて列挙型を挿入できます。

私はDescribeAllEnumsAsStringsを試しましたが、サーバーは、私たちが探しているものではない列挙型の値の代わりに文字列を受け取ります。

誰でもこれを解決しましたか?

編集:

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

ドゥスキーマに値を文字列として記述させたいが、サーバーに整数をポストしたいのですか? JSON.netは両方の値をうまく扱うため、整数のみのバージョンは明確な要件ですか? Swaggerは列と整数の両方の値を持つ列挙型をサポートしているとは思わない。 – Mig

+1

予想される動作が不明です。Swagger UIに表示する内容と、Web APIへのPOST/PUTの例を例を用いて説明してください。 –

+0

それはまさに私が欲しかったものです。整数検証が失敗したときにサーバーに送信されると、おそらく問題は自分のコード内にあります。しかし、私のデータベースでは、整数として保存されると言いますか?または、整数として保存されますか?私のデータベースに文字列として保存することは無駄になるでしょう –

答えて

59

the docsから:だから

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

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

この回答は解決策チェックマークが表示されます。 – sprinter252

+0

[EnumDataType(typeof(priority))] [JsonConverter(typeof(StringEnumConverter))] – Lineker

+0

thatsクリーンありがとう –

14

:あなたが唯一の特定の種類とプロパティでこの動作が必要な場合は

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

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

また、StringEnumConverterを使用私も同様の問題があると思います。私は、int型の文字列マッピングと一緒に列挙型を生成するためにswaggerを探しています。 APIはintを受け入れる必要があります。私が本当に欲しいのは、反対側の「本当の」列挙型のコード生成です(この場合、改造を使ったアンドロイドアプリ)。

私の研究では、これはSwaggerが使用するOpenAPI仕様の限界と思われます。 enumの名前と数値を指定することはできません。

ベストプラクティスはhttps://github.com/OAI/OpenAPI-Specification/issues/681ですが、「まもなく」のように見えますが、スワッガーは更新する必要があり、スワッシュバックルも更新する必要があります。

私の回避策は、列挙型を探して関連する説明に列挙型の内容を取り込むドキュメントフィルタを実装することでした。

 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()); 
    } 

} 

これはあなたの闊歩-UI上で、次のようなものになりそう少なくともあなたは "あなたがやっているものを見る" ことができます。 enter image description here

+0

+1私は列挙型に説明を追加しようとしていましたが(単に「列挙型を記述する」)、これは考えられませんでした。私は既に他のフィルタを用意していますが、もっと「オーガニック」なものを探していましたが、サポートはありません。さて、すべての方法でフィルタリング:) – NSGaga