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

Viewed 7590

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?

3 Answers

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

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!

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