question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

5.0.0-rc2 schema filter for [FromForm] request bodies?

See original GitHub issue

I have a controller method:

[HttpPost]
public ActionResult Foo([FromForm]MyRequestType request) => Ok();

//...
public class MyRequestType
{
      [BindProperty(Name = "email")]
      [Schema(Format="email")]
      public string Email { get; set; }
}

and a schema filter:

    public class SchemaAttribute : Attribute
    {
        public string Format { get; set; }
    }
    public class MyFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
            => Apply(schema, context, null);
        private void Apply(OpenApiSchema schema, SchemaFilterContext context, SchemaAttribute attribute)
        {
            if (attribute == null) { attribute = context.Type.GetCustomAttribute<SchemaAttribute>(); }
            Process(schema, attribute);
            foreach (var property in context.Type.GetProperties())
            {
                var name = property.GetCustomAttribute<BindPropertyAttribute>()?.Name;
                if (name == null) continue;
                if (!schema.Properties.TryGetValue(name, out var schemaProp)) continue;
                var attr = property.GetCustomAttribute<SchemaAttribute>();
                if (attr != null)
                {
                    Apply(schemaProp, new SchemaFilterContext(property.PropertyType,null,null,null), attr);
                }
            }
        }

        private void Process(OpenApiSchema schema, SchemaAttribute attribute)
        {
            if (attribute == null) return;

            if (attribute.Format != null)
            {
                schema.Format = attribute.Format;
            }
        }
    }

(code reduced for test case)

expecting:

    "requestBody": {
      "content": {
        "multipart/form-data": {
          "schema": {
            "type": "object",
            "properties": {
              "email": {
                "type": "string",
                "format": "email"
              }
            }
          },
          "encoding": {
            "email": {
              "style": "form"
            }
          }
        }
      }
    },

actual:

same as above except “format”:… missing

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (3 by maintainers)

github_iconTop GitHub Comments

2reactions
bbarrycommented, May 9, 2019

Without much testing I am able to trigger schema generation via an operation filter which appears to be working for me:

internal class FixFromFormSchemaOperationFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        var fromFormParameter = context.MethodInfo.GetParameters()
            .FirstOrDefault(p => p.IsDefined(typeof(FromFormAttribute), true));
        if (fromFormParameter == null) return;
        
        foreach (var key in operation.RequestBody.Content.Keys)
        {
            operation.RequestBody.Content[key].Schema =
                context.SchemaGenerator.GenerateSchema(fromFormParameter.ParameterType, context.SchemaRepository);
        }
    }
}

I am not sure what the potential drawbacks are of this approach (all of my cases have a single parameter with [FromForm] which is a class containing a set of string, enum, and primitive properties).

0reactions
domaindrivendevcommented, Jan 17, 2021

Due to the way in which form fields are surfaced by ApiExplorer (the API metadata layer that ships with ASP.NET Core), form Schema’s need to be treated as a special case in Swashbuckle, and are generated in a slightly different way to to regular payload schemas.

As a result, they are a) always generated inline within the relevent Operation definition rather components.schemas and b) never passed through the schema filters.

If you need to inspect those schemas, look in the relevent Operation definition instead. If you need to modify, use an IOperationFilter instead of an ISchemaFilter.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Ignore [FromForm] data from rendering on swagger
1 Answer 1 ; SwaggerIgnoreFilter : ISchemaFilter ; 0) return ; // In v5.3.3+ use Type instead .GetFields(bindingFlags).Cast<MemberInfo>() .Concat( ...
Read more >
Describing Request Body
OpenAPI 3.0 provides the requestBody keyword to describe request bodies. ... anyOf and oneOf can be used to specify alternate schemas.
Read more >
Generating Swagger example requests with Swashbuckle
Sorting as in the the XML request body the swagger generates from the webapi…I need that to be in alphabetical order that is...
Read more >
Filters in ASP.NET Core
The filter pipeline runs after ASP.NET Core selects the action to execute: The request is processed through Other Middleware, Routing Middleware ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found