Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Length] Attribute isn't supported #2756

Closed
satma0745 opened this issue Jan 9, 2024 · 9 comments · Fixed by #2882
Closed

[Length] Attribute isn't supported #2756

satma0745 opened this issue Jan 9, 2024 · 9 comments · Fixed by #2882
Milestone

Comments

@satma0745
Copy link
Contributor

This issue is a feature request for a support of the [Length] attribute. Judging by the example in the Contribution guide, this issue falls into the Feature Requests category.

The System.ComponentModel.DataAnnotations namespace has 3 (actually even more, but it is not within the scope of this Issue) Attributes responsible for the string length validation:

  1. [MinLength(length)] - MS Docs
  2. [MaxLength(length)] - MS Docs
  3. [Length(minimumLength, maximumLength)] - MS Docs

And while the first two are supported, the latter isn't.
Suppose, we have the following DTO definition:

class Dto
{
    [MinLength(2), MaxLength(10)]
    public string Prop1 { get; set; }

    [Length(2, 10)]
    public string Prop2 { get; set; }
}

Having such model SwaggerGen produces the following OpenApi specification:

"Dto": {
  "type": "object",
  "properties": {
    "prop1": {
      "maxLength": 10,  
      "minLength": 2,
      "type": "string",
      "nullable": true
    },
    "prop2": {
      "type": "string",
      "nullable": true
    }
  },
  "additionalProperties": false
}

Where the prop1 field has both maxLength and minLength values specified, but the prop2 field doesn't have them at all.

@satma0745
Copy link
Contributor Author

It turns out that the Project has not been updated for a year (at this point in time). This means that the current version for the project is .Net 7.0, while the [Length] attribute was introduced in .Net 8.0. It's impossible to add support for this attribute at the moment.

@satma0745
Copy link
Contributor Author

satma0745 commented Jan 10, 2024

If You stumbled upon this Issue and the Project hasn't yet migrated to .Net 8, then you can make use of the following SchemaFilter in Your Solution:

internal sealed class LengthAttributeSupportSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.MemberInfo is null)
        {
            return;
        }

        var lengthAttributes = context.MemberInfo.GetInlineAndMetadataAttributes().OfType<LengthAttribute>();
        foreach (var lengthAttribute in lengthAttributes)
        {
            ApplyLengthAttribute(schema, lengthAttribute);
        }
    }

    private void ApplyLengthAttribute(OpenApiSchema schema, LengthAttribute lengthAttribute)
    {
        if (schema.Type == "array")
        {
            schema.MinItems = schema.MinItems is null 
                ? lengthAttribute.MinimumLength 
                : Math.Max(schema.MinItems.Value, lengthAttribute.MinimumLength);

            schema.MaxItems = schema.MaxItems is null
                ? lengthAttribute.MaximumLength
                : Math.Min(schema.MaxItems.Value, lengthAttribute.MaximumLength);
        }
        else
        {
            schema.MinLength = schema.MinLength is null 
                ? lengthAttribute.MinimumLength 
                : Math.Max(schema.MinLength.Value, lengthAttribute.MinimumLength);

            schema.MaxLength = schema.MaxLength is null
                ? lengthAttribute.MaximumLength
                : Math.Min(schema.MaxLength.Value, lengthAttribute.MaximumLength);
        }
    }
}

Warning

I needed [Length] attribute support for models only, so in this example I'm retrieving the list of attributes from the context.MmemberInfo. If You need support for this attribute in other cases, then You need to change the context.MemberInfo.GetInlineAndMetadataAttributes() call.

@satma0745
Copy link
Contributor Author

I'm not closing this Issue, since the solution I've provided is temporary. I hope that the Project'll migrate to the .Net 8 eventually and we'll be able to add support for the [Length] attribute on the Project's source-code side.

@soroshsabz
Copy link

ITNOA

I need this feature too.

Copy link
Contributor

This issue is stale because it has been open for 60 days with no activity. It will be automatically closed in 14 days if no further updates are made.

@github-actions github-actions bot added the stale Stale issues or pull requests label Apr 14, 2024
@martincostello martincostello added help-wanted A change up for grabs for contributions from the community and removed stale Stale issues or pull requests labels Apr 14, 2024
@dnperfors
Copy link
Contributor

I wanted to help you out by implementing this, but I need .NET 8 support for this... Guess I will start with reviewing the .NET 8 PR instead :)

@soroshsabz
Copy link

@satma0745 @dnperfors As you can see, .NET 8 added in PR #2799 and merge it.

So do you can start implementing this feature?

thanks

@satma0745
Copy link
Contributor Author

@soroshsabz
Yeah, I'll start working on it

@satma0745
Copy link
Contributor Author

@soroshsabz Opened a PR: #2882

@martincostello martincostello removed the help-wanted A change up for grabs for contributions from the community label May 14, 2024
@martincostello martincostello added this to the v6.6.2 milestone May 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants