Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mark a property as required in Swagger, without ASP.NET model validation?

I am creating a public API that uses multiple private APIs (can not be accessed from outside). Business validations have been written for the private APIs and I do not want to re-write them for the public API. But I do want the swagger documentation to be the same.

That is why I wonder if I can mark property as mandatory, without using the Required attribute of ASP.NET. But that the swagger documentation indicates that it is mandatory. Is this possible?

like image 937
Undeadparade Avatar asked Nov 15 '18 12:11

Undeadparade


People also ask

Does swagger do validation?

Well, Swagger Editor does add it's own additional layer of error recognition on top of JSON Schema validation.

How do I hide property in swagger?

6. Using @ApiParam. @ApiParam is also a Swagger annotation that we can use to specify metadata related to request parameters. We can set the hidden property to true in order to hide any property.

What is AddSwaggerGen?

AddSwaggerGen is an extension method to add swagger services to the collection. To configure Swagger, you invoke the method SwaggerDoc. Passing an Info object, you can define the title, description, contact information, and more in code file Startup.


3 Answers

Yes, it's possible. Add your custom class implementing IOperationFilter

public class UpdateParametersAsRequired : IOperationFilter
{
    public void Apply(Operation operation, SchemaRegistry s, ApiDescription a)
    {
        if (operation.OperationId == "ControllerName_Action")
        {
            if (operation.Parameters != null)
            {
                foreach (var parameter in operation.Parameters)
                {
                    if (parameter.Name == "ParameterYouWantToEdit")
                    { 
                        // You can edit the properties here
                        parameter.Required = true;
                    }
                }
            }
            else
            {
              // Add parameters if doesn't exists any
                operation.Parameters = new List<IParameter>();
                operation.Parameters.Add(
                    new Parameter
                    {
                        name = "ParameterName",
                        @in = "body",
                        @default = "123",
                        type = "string",
                        description = "x y z",
                        required = true
                    }
                );
            }
        }
    }
}

Cheers!

like image 105
Mohsin Avatar answered Oct 09 '22 11:10

Mohsin


Thanks to Mohsin, I solved my problem. The following I came up with, I created an attribute called SwaggerRequired. This attribute can be placed on any model. The AddSwaggerRequiredSchemaFilter then ensures that the Swagger documentation is modified. See below the code I wrote for this

A random model:

public class Foo
{
    [SwaggerRequired]
    public string FooBar{ get; set; }
}

The SwaggerRequiredAttribute:

[AttributeUsage(AttributeTargets.Property)] 
public class SwaggerRequiredAttribute : Attribute
{
}

And the AddSwaggerRequiredSchemaFilter to get it working:

public class AddSwaggerRequiredSchemaFilter : ISchemaFilter
{
    public void Apply(Swashbuckle.Swagger.Schema schema, SchemaRegistry schemaRegistry, Type type)
    {
        PropertyInfo[] properties = type.GetProperties();
        foreach (PropertyInfo property in properties)
        {
            var attribute = property.GetCustomAttribute(typeof(SwaggerRequiredAttribute));

            if (attribute != null)
            {
                var propertyNameInCamelCasing = char.ToLowerInvariant(property.Name[0]) + property.Name.Substring(1);

                if (schema.required == null)
                {
                    schema.required = new List<string>()
                    {
                        propertyNameInCamelCasing
                    };
                }
                else
                {
                    schema.required.Add(propertyNameInCamelCasing);
                }
            }
        }
    }
}
like image 43
Undeadparade Avatar answered Oct 09 '22 11:10

Undeadparade


I know its late. But someone else might get helped.

We can add [JsonRequired] over the properties which are needed to be required. Further, add the following code to suppress the validation error.

    [OnError]
    internal void OnError(StreamingContext context, ErrorContext errorContext)
    {
        errorContext.Handled = true;
    }

Over all, it would be like this:

    public class Model
    {
        [JsonRequired]
        public Property {get; set;}
        
        [OnError]
        internal void OnError(StreamingContext context, ErrorContext errorContext)
        {
            errorContext.Handled = true;
        }
    }
like image 25
Mehawk Avatar answered Oct 09 '22 10:10

Mehawk