स्वैगर यूआई वेब एप के दस्तावेज स्ट्रिंग्स के रूप में प्रस्तुत करते हैं?


107

क्या सभी एनमों को उनके इंट वैल्यू के बजाय स्वैगर में उनके स्ट्रिंग मूल्य के रूप में प्रदर्शित करने का एक तरीका है?

मैं हर बार एनम को देखने के बिना 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 दोनों मानों को ठीक से संभाल लेगा, इसलिए पूर्णांक केवल एक निश्चित आवश्यकता है? मुझे नहीं लगता कि स्वैगर एक स्ट्रिंग और पूर्णांक मान दोनों के साथ एक एनम प्रकार का समर्थन करता है।
हक्स

1
आपका अपेक्षित व्यवहार स्पष्ट नहीं है, क्या आप बेहतर तरीके से समझा सकते हैं कि आप स्वैगर यूआई को क्या प्रदर्शित करना चाहते हैं और उदाहरणों के साथ अपने वेब एपीआई के लिए पोस्ट / पूट करना चाहते हैं?
फेडेरिको डिपुमा

इसके अलावा, अगर मेरे पास GET के तरीके हैं जो url में एनम को लेते हैं, तो मैं चाहता हूं कि यह योजना सुझाए गए मूल्यों की ड्रॉप डाउन सूची में स्ट्रिंग के रूप में वर्णन करे

पूर्णांक सत्यापन विफल क्यों होता है? मॉडल में टाइप एक एनम होना चाहिए और json मीडिया फॉर्मेटर सही तरीके से या तो स्ट्रिंग या इंट को हैंडल करेगा। यदि आप प्रश्न को एक उदाहरण से अपडेट करते हैं तो यह समझने में हमारी मदद करेगा कि सत्यापन विफल क्यों हो रहा है।
हक्स

4
यदि यह एक झंडे का प्रतीक है, तो इसे संख्यात्मक होना चाहिए, जब तक कि आपके पास हर संभव संयोजन के झंडे के लिए परिभाषित मान न हों। यह पागल है कि स्वैगर प्रत्येक एनम के लिए बीओटीएच नाम और मूल्य प्रदर्शित नहीं करता है, और इसके बजाय अकेले नंबर (बेकार) या अकेले नाम दिखाता है (फिर से, झंडे के लिए बेकार जो संख्या के रूप में निर्दिष्ट किया जाना चाहिए)।
त्रिनको

जवाबों:


188

से डॉक्स :

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

5
यह मेरे लिए काम नहीं करता [EnumDataType (typeof (प्राथमिकता))] [JsonConverter (typeof (StringEnumConverter))]।
लाइनकर

@NH। हां, मैंने
Lineker

@Lineker, इस गाइड का अनुसरण करते हुए अपनी त्रुटि को एक नए प्रश्न के रूप में पोस्ट करें: stackoverflow.com/help/mcve
NH।

धन्यवाद! मुझे लगता है कि मैं आपकी टिप्पणी को स्रोत में भी छोड़ सकता हूँ #thwwilldothetrick
Simon_Weaver

5
DescribeAllEnumsAsStringsनियंत्रक गुणों पर ऑब्जेक्ट गुणों और यहां तक ​​कि क्वेरी मापदंडों के लिए काम किया। हालांकि, उपयोग करना EnumDataTypeAttributeऔर JsonConverter(typeof(StringEnumConverter))मेरे लिए काम नहीं किया।
बगेड87

90

Microsoft JSON लाइब्रेरी के साथ ASP.NET Core 3 के लिए (System.Text.Json)

Startup.cs / ConfigureServices () में:

services
    .AddControllersWithViews(...) // or AddControllers() in a Web API
    .AddJsonOptions(options => 
        options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));

ASP.NET Core 3 के लिए Json.NET (Newtonsoft.Json) लाइब्रेरी के साथ

Swashbuckle.AspNetCore.Newtonsoftपैकेज स्थापित करें ।

Startup.cs / ConfigureServices () में:

services
    .AddControllersWithViews(...)
    .AddNewtonsoftJson(options => 
        options.SerializerSettings.Converters.Add(new StringEnumConverter()));
// order is vital, this *must* be called *after* AddNewtonsoftJson()
services.AddSwaggerGenNewtonsoftSupport();

ASP.NET कोर 2 के लिए

Startup.cs / ConfigureServices () में:

services
    .AddMvc(...)
    .AddJsonOptions(options => 
        options.SerializerSettings.Converters.Add(new StringEnumConverter()));

प्री-ASP.NET कोर

httpConfiguration
    .EnableSwagger(c => 
        {
            c.DescribeAllEnumsAsStrings();
        });

4
विकल्पों का उपयोग करने की समस्या। SerializerSettings.Converters.Add (नया StringEnumConverter ())) यह है कि आपके सभी तरीकों के लिए जोंस को बदलना, न केवल Sawshbuckle के लिए।
Guillaume

क्या किसी के पास Azure Functions v2 और / या v3 का हल है?
डैन फ्रीडमैन

@DanFriedman Swashbuckle को ध्यान में रखते हुए एज़्योर फ़ंक्शंस के साथ काम नहीं करता है, आप भाग्य से बाहर हैं।
इयान केम्प

@IanKemp AzureExtensions.Swashbuckleपैकेज के साथ थर्ड पार्टी सपोर्ट है, लेकिन @DanFriedman की तरह मैं उम्मीद के
मुताबिक

40

इसलिए मुझे लगता है कि मुझे भी इसी तरह की समस्या है। मैं int -> स्ट्रिंग मैपिंग के साथ-साथ एनम उत्पन्न करने के लिए स्वैगर की तलाश कर रहा हूं। एपीआई को इंट को स्वीकार करना चाहिए। स्वैगर-उई कम मायने रखता है, जो मैं वास्तव में चाहता हूं वह दूसरी तरफ "वास्तविक" एनम के साथ कोड पीढ़ी है (इस मामले में रेट्रोफिट का उपयोग करके एंड्रॉइड ऐप)।

इसलिए मेरे शोध से यह अंततः ओपनएपीआई विनिर्देश की एक सीमा लगती है जिसका उपयोग स्वैगर करता है। एनम के लिए नाम और संख्या निर्दिष्ट करना संभव नहीं है।

मेरे द्वारा अनुसरण किया गया सबसे अच्छा मुद्दा https://github.com/OAI/OpenAPI-Specification/issues/681 है जो "शायद जल्द ही" जैसा दिखता है, लेकिन तब स्वैगर को अपडेट करना होगा, और मेरे मामले में Swashbatle के रूप में कुंआ।

अभी के लिए मेरा वर्कअम एक डॉक्यूमेंट फ़िल्टर लागू करना है जो एनम के लिए दिखता है और एन्नम की सामग्री के साथ प्रासंगिक विवरण को पॉप्युलेट करता है।

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

}

इसका परिणाम आपके स्वैगर-उई पर निम्न की तरह होता है ताकि आप कम से कम "यह देख सकें कि आप क्या कर रहे हैं": यहां छवि विवरण दर्ज करें


1
+1 मैं विवरणों को एनुम्स में जोड़ना चाह रहा था (बस 'एनम का वर्णन करने के लिए'), इस बारे में कभी नहीं सोचा था। मेरे पास पहले से ही जगह में फिल्टर हैं, लेकिन कुछ और 'ऑर्गेनिक' की तलाश में थे, लेकिन कोई सहारा नहीं है। फिर, सभी तरह से फ़िल्टर करता है :)
NSGaga-ज्यादातर-निष्क्रिय

धन्यवाद! मैंने इसे अपने प्रोजेक्ट में इस्तेमाल किया, लेकिन इसे .NET कोर के साथ काम करने के लिए संशोधित किया। मैंने उत्तर के रूप में अपना कार्यान्वयन जोड़ा।
गेब्रियल लुसी

27

ASP.NET कोर 3.1

न्यूटनसॉफ्ट JSON का उपयोग करके स्ट्रिंग्स के रूप में एनम उत्पन्न करने के लिए आपको स्पष्ट रूप से न्यूटनसॉफ्ट सपोर्ट AddSwaggerGenNewtonsoftSupport()को निम्न प्रकार से जोड़ना होगा :

services.AddMvc()
    ...
    .AddNewtonsoftJson(opts =>
    {
        opts.SerializerSettings.Converters.Add(new StringEnumConverter());
    });


services.AddSwaggerGen(...);
services.AddSwaggerGenNewtonsoftSupport(); //

यह एक नए पैकेज के माध्यम से उपलब्ध है Swashbuckle.AspNetCore.Newtonsoft। ऐसा लगता है कि एनम कनवर्टर समर्थन के अलावा इस पैकेज के बिना सब कुछ ठीक काम करता है।


1
यह इस सम्मेलन को विश्व स्तर पर स्थापित करने में मदद करता है, लेकिन यदि आपको इसे केवल कुछ प्रकार के एनमों पर लागू करने की आवश्यकता है, तो आपको इस मुद्दे को ध्यान से पढ़ने की आवश्यकता होगी । टी एल; DR: नए StringEnumConverter () को केवल प्रॉपर्टी पर लागू करना संभव नहीं है, लेकिन आप इसे पूरी तरह से लागू कर सकते हैं।
ए। त्रेताकोव

1
मुझे लगता है कि अगर हम गोच की बात कर रहे हैं, तो पूरी तरह से कस्टम कनवर्टर का उपयोग करना भी संभव नहीं है। स्वैगर कस्टम कनवर्टर के माध्यम से एनम मूल्यों को नहीं चलाता है; यह बस StringEnumConverterएक विशेष मामले के रूप में पहचानता है ।
रोमन स्टार्कोव

22

मैं .NET कोर एप्लीकेशन में rory_za के उत्तर का उपयोग करना चाहता था, लेकिन मुझे इसे काम करने के लिए थोड़ा संशोधित करना पड़ा। यहाँ कार्यान्वयन है। मैं .NET कोर के लिए आया हूं।

मैंने इसे बदल भी दिया, इसलिए यह अंतर्निहित प्रकार को नहीं मानता है 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)}";
    }
}

फिर इसे ConfigureServicesStartup.cs में अपनी विधि में जोड़ें :

c.DocumentFilter<EnumDocumentFilter>();

Enum को हटाना संभव: Array [6] जो नीचे दिखाई देता है?
सॉफ्टलियन

4
महान समाधान, लेकिन DescribeEnumParametersमेरे प्रोजेक्ट में एक्सटेंशन खाली थे। मैं कास्ट करने के लिए किया था paramके लिए NonBodyParameterऔर enum जाँच वहाँ:if (param is NonBodyParameter nbParam && nbParam.Enum?.Any() == true) { param.Description += DescribeEnum(nbParam.Enum); }
Rabban

मेरी परियोजना पर एक्सटेंशन भी खाली है, @ रब्बन समाधान का उपयोग किया।
कार्लोस बेपरलर

1
@ रब्बन I ने इसे शामिल करने के लिए अपना कोड अपडेट किया। क्या आप यह सत्यापित कर सकते हैं कि मैंने इसे सही जगह पर रखा है? मेरे पास यह मुद्दा नहीं था। शायद एक नए संस्करण ने चीजों को बदल दिया।
गैब्रियल लुसी

@GabrielLuci ने पुष्टि की और अनुमोदित;)
रब्बन

12

Asp.net कोर 3 के साथ

using System.Text.Json.Serialization;

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
         services.AddControllers().AddJsonOptions(options =>
             options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()));

लेकिन ऐसा लगता है कि Swashbuckle वर्जन 5.0.0-rc4 इसका समर्थन करने के लिए तैयार नहीं है। इसलिए हमें Swashbuckle config फ़ाइल में एक विकल्प (पदावनत) का उपयोग करने की आवश्यकता है, जब तक कि वह इसका समर्थन नहीं करता है और इसे Newtonsoft लाइब्रेरी की तरह दर्शाता है।

public void ConfigureServices(IServiceCollection services)
{ 
      services.AddSwaggerGen(c =>
      {
            c.DescribeAllEnumsAsStrings();

इस उत्तर और अन्य उत्तरों के बीच का अंतर न्यूटनसॉफ्ट के बजाय केवल Microsoft JSON लाइब्रेरी का उपयोग कर रहा है।


अरे @ बशीर, क्या उस समर्थन की कमी पर नज़र रखने के लिए एक स्वैछक मुद्दा है?
बर्नार्ड वेंडर बीकन

हाय @ बर्नार्ड-वेंडर-बीकेन, मैंने रिपोर्ट नहीं किया है लेकिन मुझे लगता है कि वहाँ है। यह अच्छा है अगर हम इसे पा सकते हैं और बाद में अपडेट के लिए इस पोस्ट में जोड़ सकते हैं।
बशीर मोमे

2
इसकी तरह दिखता है: github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1269
jeremyh

10

.NET कोर 3.1 और SWAGGER 5

यदि आपको स्ट्रिंग्स के रूप में पारित किए गए शत्रुओं को चुनने के लिए एक सरल समाधान की आवश्यकता है :

using System.Text.Json.Serialization;


[JsonConverter(typeof(JsonStringEnumConverter))]
public enum MyEnum
{
    A, B
}

ध्यान दें, हम System.Text.Json.Serializationनाम स्थान का उपयोग करते हैं , नहीं Newtonsoft.Json!


यह एक उचित मान दिखाते हुए काम करता है, और यह भी काम करता है जब मानों को एनम में वापस परिवर्तित करता है। ध्यान दें कि आपको NuGet पैकेज जोड़ने की आवश्यकता है System.Text.Json
MovGP0

यही मैं ढूंढ रहा था! जैसा कि मुझे सिर्फ एक एनम के लिए स्ट्रिंग का उपयोग करना है, और DescribeAllEnumsAsStringsसभी एनम को स्ट्रिंग में बदल देगा।
निलय

9

अगर किसी को दिलचस्पी है तो मैंने काम करने के लिए कोड को संशोधित किया है

.NET कोर 3 और स्वैगर V5

    public class SwaggerAddEnumDescriptions : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        // add enum descriptions to result models
        foreach (var property in swaggerDoc.Components.Schemas.Where(x => x.Value?.Enum?.Count > 0))
        {
            IList<IOpenApiAny> propertyEnums = property.Value.Enum;
            if (propertyEnums != null && propertyEnums.Count > 0)
            {
                property.Value.Description += DescribeEnum(propertyEnums, property.Key);
            }
        }

        // add enum descriptions to input parameters
        foreach (var pathItem in swaggerDoc.Paths.Values)
        {
            DescribeEnumParameters(pathItem.Operations, swaggerDoc);
        }
    }

    private void DescribeEnumParameters(IDictionary<OperationType, OpenApiOperation> operations, OpenApiDocument swaggerDoc)
    {
        if (operations != null)
        {
            foreach (var oper in operations)
            {
                foreach (var param in oper.Value.Parameters)
                {
                    var paramEnum = swaggerDoc.Components.Schemas.FirstOrDefault(x => x.Key == param.Name);
                    if (paramEnum.Value != null)
                    {
                        param.Description += DescribeEnum(paramEnum.Value.Enum, paramEnum.Key);
                    }
                }
            }
        }
    }

    private Type GetEnumTypeByName(string enumTypeName)
    {
        return AppDomain.CurrentDomain
            .GetAssemblies()
            .SelectMany(x => x.GetTypes())
            .FirstOrDefault(x => x.Name == enumTypeName);
    }

    private string DescribeEnum(IList<IOpenApiAny> enums, string proprtyTypeName)
    {
        List<string> enumDescriptions = new List<string>();
        var enumType = GetEnumTypeByName(proprtyTypeName);
        if (enumType == null)
            return null;

        foreach (OpenApiInteger enumOption in enums)
        {
            int enumInt = enumOption.Value;

            enumDescriptions.Add(string.Format("{0} = {1}", enumInt, Enum.GetName(enumType, enumInt)));
        }

        return string.Join(", ", enumDescriptions.ToArray());
    }
}

1
यह केवल तभी काम करता है जब पैरामीटर प्रकार बिल्कुल enum है ... अशक्त एनम नहीं, enums का संग्रह आदि उन मामलों के लिए मेरा उत्तर जांचें।
मटियास

4

मैंने बस यही किया और यह ठीक काम करता है!

Startup.cs

services.AddSwaggerGen(c => {
  c.DescribeAllEnumsAsStrings();
});

Model.cs

public enum ColumnType {
  DATE = 0
}

swagger.json

type: {
  enum: ["DATE"],
  type: "string"
}

मुझे उम्मीद है कि यह आपकी मदद करता है कि यह कैसे मेरी मदद करता है!


2
DescribeAllEnumsAsStringsपदावनत किया जाता है
Node.JS

4

, .net कोर 3.1 और स्वैगर 5.0.0:

using System.Linq;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

namespace WebFramework.Swagger
{
    public class EnumSchemaFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            if (context.Type.IsEnum)
            {
                var enumValues = schema.Enum.ToArray();
                var i = 0;
                schema.Enum.Clear();
                foreach (var n in Enum.GetNames(context.Type).ToList())
                {
                    schema.Enum.Add(new OpenApiString(n + $" = {((OpenApiPrimitive<int>)enumValues[i]).Value}"));
                    i++;
                }
            }
        }
    }

}

और Startup.cs में:

services.AddSwaggerGen(options =>
            {
                #region  EnumDesc
                options.SchemaFilter<EnumSchemaFilter>();
                #endregion
            });

परिणाम


4
इसके नीचे का पक्ष यह है कि जब किसी अनुरोध को निष्पादित करते हैं, तो एक एनम वैल्यू के केवल इंट प्रतिनिधित्व (उदाहरण के लिए 2) पास करने के बजाय एपीआई को पूर्ण विवरण मान के रूप में मिलेगा (जैसे LogicError = 3), जो एक के रूप में विफल हो जाएगा बुरा अनुरोध क्योंकि यह एनम के लिए मान्य मूल्य नहीं है।
मत्ती

3

मूल्यों के साथ एनम डंक के लिए मेरा संस्करण:

यहां छवि विवरण दर्ज करें

कॉन्फ़िगर सेवा:

services.AddSwaggerGen(c =>
            {
                c.SwaggerDoc("v1", new OpenApiInfo { Title = "web server api", Version = "v1" });
                c.SchemaFilter<EnumSchemaFilter>();
            });

फिल्टर:

public class EnumSchemaFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema model, SchemaFilterContext context)
        {
            if (context.Type.IsEnum)
            {
                model.Enum.Clear();
                Enum.GetNames(context.Type)
                    .ToList()
                    .ForEach(name => model.Enum.Add(new OpenApiString($"{Convert.ToInt64(Enum.Parse(context.Type, name))} - {name}")));
            }
        }
    }

2

Startup.cs के अंदर कोड लिखें

services.AddSwaggerGen(c => {
      c.DescribeAllEnumsAsStrings();
    });

2
यह विकल्प Swashbuckle में पदावनत है। यह ASP.NET कोर विकल्प का उपयोग करने के लिए अनुशंसित है और फिर Swashbuckle को प्रतिबिंबित कर सकता है।
बशीर मोमन

2

मुझे यहाँ अच्छा काम मिला है:

@PaooVetor - ने इस तरह से शेमाफिल्टर का उपयोग कर हल किया:

public class EnumSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema model, SchemaFilterContext context)
    {
        if (context.Type.IsEnum)
        {
            model.Enum.Clear();
            Enum.GetNames(context.Type)
                .ToList()
                .ForEach(n => model.Enum.Add(new OpenApiString(n)));
            }
        }
    }
}

और Startup.cs में:

services.AddSwaggerGen(options =>
{
    options.SchemaFilter<EnumSchemaFilter>();
}

आपको यह भी सुनिश्चित करना चाहिए कि आप इसे अपडेट कर model.Formatदें "string"क्योंकि यह आम तौर पर होगा "int32"
larearez

1

.नेट कोर 3.0

   using Newtonsoft.Json.Converters;

 services
    .AddMvc(options =>
    {
     options.EnableEndpointRouting = false;
     })
    .AddNewtonsoftJson(options => options.SerializerSettings.Converters.Add(new StringEnumConverter()))

1
यह नए asp.net कोर JSON serialization के बजाय Newtonsoft का उपयोग कर रहा है।
बशीर मोमन

1

मैंने होसाम रेहानी के जवाब को अशक्त एनमों के साथ काम करने और एनमों के संग्रह के साथ संशोधित किया है। पिछला उत्तर भी तभी काम करता है जब किसी संपत्ति का नाम ठीक उसी तरह रखा जाता है जैसे वह टाइप करता है। इन सभी समस्याओं को नीचे दिए गए कोड में संबोधित किया गया है।

यह .net core 3.x और swagger 5.x के साथ काम करता है।

कुछ मामलों में दो बार एनम प्रकार की खोज न करने से यह अधिक कुशल हो सकता है।

class SwaggerAddEnumDescriptions : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        // add enum descriptions to result models
        foreach (var property in swaggerDoc.Components.Schemas.Where(x => x.Value?.Enum?.Count > 0))
        {
            IList<IOpenApiAny> propertyEnums = property.Value.Enum;
            if (propertyEnums != null && propertyEnums.Count > 0)
            {
                property.Value.Description += DescribeEnum(propertyEnums, property.Key);
            }
        }

        // add enum descriptions to input parameters
        foreach (var pathItem in swaggerDoc.Paths)
        {
            DescribeEnumParameters(pathItem.Value.Operations, swaggerDoc, context.ApiDescriptions, pathItem.Key);
        }
    }

    private void DescribeEnumParameters(IDictionary<OperationType, OpenApiOperation> operations, OpenApiDocument swaggerDoc, IEnumerable<ApiDescription> apiDescriptions, string path)
    {
        path = path.Trim('/');
        if (operations != null)
        {
            var pathDescriptions = apiDescriptions.Where(a => a.RelativePath == path);
            foreach (var oper in operations)
            {
                var operationDescription = pathDescriptions.FirstOrDefault(a => a.HttpMethod.Equals(oper.Key.ToString(), StringComparison.InvariantCultureIgnoreCase));
                foreach (var param in oper.Value.Parameters)
                {
                    var parameterDescription = operationDescription.ParameterDescriptions.FirstOrDefault(a => a.Name == param.Name);
                    if (parameterDescription != null && TryGetEnumType(parameterDescription.Type, out Type enumType))
                    {
                        var paramEnum = swaggerDoc.Components.Schemas.FirstOrDefault(x => x.Key == enumType.Name);
                        if (paramEnum.Value != null)
                        {
                            param.Description += DescribeEnum(paramEnum.Value.Enum, paramEnum.Key);
                        }
                    }
                }
            }
        }
    }

    bool TryGetEnumType(Type type, out Type enumType)
    {
        if (type.IsEnum)
        {
            enumType = type;
            return true;
        }
        else if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            var underlyingType = Nullable.GetUnderlyingType(type);
            if (underlyingType != null && underlyingType.IsEnum == true)
            {
                enumType = underlyingType;
                return true;
            }
        }
        else
        {
            Type underlyingType = GetTypeIEnumerableType(type);
            if (underlyingType != null && underlyingType.IsEnum)
            {
                enumType = underlyingType;
                return true;
            }
            else
            {
                var interfaces = type.GetInterfaces();
                foreach (var interfaceType in interfaces)
                {
                    underlyingType = GetTypeIEnumerableType(interfaceType);
                    if (underlyingType != null && underlyingType.IsEnum)
                    {
                        enumType = underlyingType;
                        return true;
                    }
                }
            }
        }

        enumType = null;
        return false;
    }

    Type GetTypeIEnumerableType(Type type)
    {
        if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(IEnumerable<>))
        {
            var underlyingType = type.GetGenericArguments()[0];
            if (underlyingType.IsEnum)
            {
                return underlyingType;
            }
        }

        return null;
    }

    private Type GetEnumTypeByName(string enumTypeName)
    {
        return AppDomain.CurrentDomain
            .GetAssemblies()
            .SelectMany(x => x.GetTypes())
            .FirstOrDefault(x => x.Name == enumTypeName);
    }

    private string DescribeEnum(IList<IOpenApiAny> enums, string proprtyTypeName)
    {
        List<string> enumDescriptions = new List<string>();
        var enumType = GetEnumTypeByName(proprtyTypeName);
        if (enumType == null)
            return null;

        foreach (OpenApiInteger enumOption in enums)
        {
            int enumInt = enumOption.Value;

            enumDescriptions.Add(string.Format("{0} = {1}", enumInt, Enum.GetName(enumType, enumInt)));
        }

        return string.Join(", ", enumDescriptions.ToArray());
    }
}

में c.DocumentFilter<SwaggerAddEnumDescriptions>();स्वैगर कॉन्फ़िगरेशन के लिए फ़िल्टर ऐड का उपयोग करें Startup.cs


0

एएसपी नेट समाधान

मेरे एपीआई डॉक्स में संपत्ति के साथ चिन्हित होने के बावजूद एक एनम को दिखाया गया था StringEnumConverter। हम उपरोक्त उल्लिखित सभी एनमों के लिए वैश्विक सेटिंग का उपयोग नहीं कर सकते। SwaggerConfig में इस पंक्ति को जोड़ने से समस्या हल हो गई:

c.MapType<ContactInfoType>(() => new Schema { type = "string", @enum = Enum.GetNames(typeof(ContactInfoType))});

0

हम जो खोज रहे थे, उसके लिए अन्य उत्तरों में मुझे कई कमियां मिलीं, इसलिए मैंने सोचा कि मैं इस पर अपनी आपूर्ति करूंगा। हम System.Text.Json के साथ ASP.NET Core 3.1 का उपयोग कर रहे हैं, लेकिन हमारे दृष्टिकोण का उपयोग किए गए JSON धारावाहिक के बावजूद काम करता है।

हमारा लक्ष्य ASP.NET कोर एपीआई दोनों में लोअर-कैमल-कैसड एनम स्ट्रिंग मानों को स्वीकार करने के साथ-साथ स्वैगर में एक ही दस्तावेज करना था। वर्तमान में हम के उपयोग कर रहे हैं [DataContract]और[EnumMember] इसलिए यह दृष्टिकोण है कि EnumMember मान संपत्ति से निचले-ऊंट-आवरण वाले मान को ले लिया जाए और पूरे मंडल में इसका उपयोग किया जाए।

हमारे नमूना enum:

[DataContract]
public class enum Colors
{
  [EnumMember(Value="brightPink")]
  BrightPink,
  [EnumMember(Value="blue")]
  Blue
}

हम निम्नलिखित के रूप में एक ISchemaFilter का उपयोग करके Swashbuckle में EnumMember मूल्यों का उपयोग करेंगे:

public class DescribeEnumMemberValues : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type.IsEnum)
        {
            schema.Enum.Clear();

            //Retrieve each of the values decorated with an EnumMember attribute
            foreach (var member in context.Type.GetMembers())
            {
                var memberAttr = member.GetCustomAttributes(typeof(EnumMemberAttribute), false).FirstOrDefault();
                if (memberAttr != null)
                {
                    var attr = (EnumMemberAttribute) memberAttr;
                    schema.Enum.Add(new OpenApiString(attr.Value));
                }
            }
        }
    }
}

हम यह सुनिश्चित करने के लिए एक तृतीय-पक्ष NuGet पैकेज (GitHub repo ) का उपयोग कर रहे हैं कि यह नामकरण योजना ASP.NET कोर में भी उपयोग की जाती है। इसे कॉन्फ़िगर करें Startup.cs में कॉन्फ़िगर करें सेवाओं के साथ:

services.AddControllers()
  .AddJsonOptions(opt => opt.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverterWithAttributeSupport()));

अंत में, हमें अपने ISchemaFilter को Swashbuckle में पंजीकृत करने की आवश्यकता है, इसलिए निम्नलिखित को भी कॉन्फ़िगर करें सेवाओं () में जोड़ें:

services.AddSwaggerGen(c => {
  c.SchemaFilter<DescribeEnumMemberValues>();
});

GetMembers()GetMembers(BindingFlags.Static | BindingFlags.Public)केवल "ब्लू" जैसे वास्तविक घोषित एनम गुणों को सीमित करने के लिए बेहतर होगा । मैंने सदस्य को वापस करने के लिए "और" मामले को भी अनुकूलित किया [EnumMember]। कोई विशेषता नहीं होने पर ।
user2864740

0

यह मानक OpenAPI के साथ संभव नहीं है। Enums केवल उनके स्ट्रिंग मानों के साथ वर्णित हैं।

सौभाग्य से आप इसे कुछ गैर-मानक एक्सटेंशन के साथ कर सकते हैं जो आपके क्लाइंट जनरेटर द्वारा उपयोग किए जाते हैं।

NSwag सपोर्ट करता है x-enumNames

ऑटोरेस्ट सपोर्ट करता है x-ms-enum

ओपेनपी-जनरेटर समर्थन करता है x-enum-varnames

अन्य जनरेटर इन एक्सटेंशनों में से किसी एक का समर्थन कर सकते हैं या उनका अपना हो सकता है।

उत्पन्न करने के लिए x-enumNamesNSwag के लिए बनाने के निम्न स्कीमा फिल्टर:

public class EnumSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type.IsEnum)
        {
            var array = new OpenApiArray();
            array.AddRange(Enum.GetNames(context.Type).Select(n => new OpenApiString(n)));
            // NSwag
            schema.Extensions.Add("x-enumNames", array);
            // Openapi-generator
            schema.Extensions.Add("x-enum-varnames", array);
        }
    }
}

और इसे पंजीकृत करें:

services.AddSwaggerGen(options =>
{
    options.SchemaFilter<EnumSchemaFilter>();
});

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.