Swagger UI Web Api 문서 열거 형을 문자열로 표시합니까?
모든 enum을 int 값 대신 swagger의 문자열 값으로 표시하는 방법이 있습니까?
매번 enum을 보지 않고도 POST 작업을 제출하고 문자열 값에 따라 enum을 넣을 수 있기를 원합니다.
시도 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
}
에서 워드 프로세서 :
httpConfiguration
.EnableSwagger(c =>
{
c.SingleApiVersion("v1", "A title for your API");
c.DescribeAllEnumsAsStrings(); // this will do the trick
});
또한 특정 유형 및 속성에서만이 동작을 원하면 StringEnumConverter를 사용합니다.
public class Letter
{
[Required]
public string Content {get; set;}
[Required]
[EnumDataType(typeof(Priority))]
[JsonConverter(typeof(StringEnumConverter))]
public Priority Priority {get; set;}
}
그래서 비슷한 문제가 있다고 생각합니다. int-> string mapping과 함께 enum을 생성하기 위해 swagger를 찾고 있습니다. API는 int를 허용해야합니다. swagger-ui는 덜 중요합니다. 제가 정말로 원하는 것은 다른쪽에 "실제"열거 형 (이 경우 개조를 사용하는 안드로이드 앱)을 사용하여 코드를 생성하는 것입니다.
그래서 내 연구에서 이것은 궁극적으로 Swagger가 사용하는 OpenAPI 사양의 한계 인 것 같습니다. 열거 형에 이름과 숫자를 지정할 수 없습니다.
내가 찾은 가장 좋은 문제는 https://github.com/OAI/OpenAPI-Specification/issues/681 입니다. "아마 곧"처럼 보이지만 Swagger를 업데이트해야하며 제 경우에는 Swashbuckle이 잘.
현재 내 해결 방법은 열거 형을 찾고 관련 설명을 열거 형의 내용으로 채우는 문서 필터를 구현하는 것입니다.
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 = property.@enum;
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 = param.@enum;
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());
}
}
이렇게하면 swagger-ui에 다음과 같은 결과가 나타나므로 최소한 "당신이하는 일을 볼 수 있습니다".
.NET Core 애플리케이션에서 rory_za의 답변을 사용하고 싶었지만 작동하도록 약간 수정해야했습니다. 다음은 .NET Core에 대한 구현입니다.
또한 기본 유형이라고 가정하지 않고 int
값 사이에 새 줄을 사용하여 쉽게 읽을 수 있도록 변경했습니다.
/// <summary>
/// Add enum value descriptions to Swagger
/// </summary>
public class EnumDocumentFilter : IDocumentFilter {
/// <inheritdoc />
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context) {
// add enum descriptions to result models
foreach (var schemaDictionaryItem in swaggerDoc.Definitions) {
var schema = schemaDictionaryItem.Value;
foreach (var propertyDictionaryItem in schema.Properties) {
var property = propertyDictionaryItem.Value;
var propertyEnums = property.Enum;
if (propertyEnums != null && propertyEnums.Count > 0) {
property.Description += DescribeEnum(propertyEnums);
}
}
}
if (swaggerDoc.Paths.Count <= 0) return;
// add enum descriptions to input parameters
foreach (var pathItem in swaggerDoc.Paths.Values) {
DescribeEnumParameters(pathItem.Parameters);
// head, patch, options, delete left out
var possibleParameterisedOperations = new List<Operation> {pathItem.Get, pathItem.Post, pathItem.Put};
possibleParameterisedOperations.FindAll(x => x != null)
.ForEach(x => DescribeEnumParameters(x.Parameters));
}
}
private static void DescribeEnumParameters(IList<IParameter> parameters) {
if (parameters == null) return;
foreach (var param in parameters) {
if (param is NonBodyParameter nbParam && nbParam.Enum?.Any() == true) {
param.Description += DescribeEnum(nbParam.Enum);
} else if (param.Extensions.ContainsKey("enum") && param.Extensions["enum"] is IList<object> paramEnums &&
paramEnums.Count > 0) {
param.Description += DescribeEnum(paramEnums);
}
}
}
private static string DescribeEnum(IEnumerable<object> enums) {
var enumDescriptions = new List<string>();
Type type = null;
foreach (var enumOption in enums) {
if (type == null) type = enumOption.GetType();
enumDescriptions.Add($"{Convert.ChangeType(enumOption, type.GetEnumUnderlyingType())} = {Enum.GetName(type, enumOption)}");
}
return $"{Environment.NewLine}{string.Join(Environment.NewLine, enumDescriptions)}";
}
}
그런 다음 ConfigureServices
Startup.cs 의 메서드에 다음을 추가합니다 .
c.DocumentFilter<EnumDocumentFilter>();
방금했는데 잘 작동합니다!
Startup.cs
services.AddSwaggerGen(c => {
c.DescribeAllEnumsAsStrings();
});
Model.cs
public enum ColumnType {
DATE = 0
}
swagger.json
type: {
enum: ["DATE"],
type: "string"
}
이것이 저에게 도움이 되었기를 바랍니다.
Startup.cs 내부에 코드 작성
services.AddSwaggerGen(c => {
c.DescribeAllEnumsAsStrings();
});
DescribeAllEnumsAsStrings()
OP가 말했듯이 서버가 문자열을 수신하고 int를 기대하기 때문에 나를 위해 작동하지 않았습니다. 서버가 문자열을 기대할 수 있도록하려면 SerializerSettings에 StringEnumConverter를 추가해야한다고 생각하며 DescribeAllEnumsAsStrings ()를 완전히 해제 할 수 있습니다.
tl; dr : Startup.cs / ConfigureServices ()에서이 작업을 수행하면됩니다.
services
.AddMvc(...)
.AddJsonOptions(options => options.SerializerSettings.Converters.Add(new StringEnumConverter()));
'programing tip' 카테고리의 다른 글
닫기 명령을 단추에 바인딩하는 방법 (0) | 2020.11.29 |
---|---|
날짜에서 주 번호 (연도) 가져 오기 PHP (0) | 2020.11.29 |
색상 이름을 16 진수 코드로 변환하는 자바 스크립트 함수 (0) | 2020.11.29 |
오류 : Objective-C 모듈 'Firebase'를 빌드 할 수 없습니다. (0) | 2020.11.29 |
jquery 부드러운 스크롤을 앵커로? (0) | 2020.11.29 |