Giter Site home page Giter Site logo

Comments (9)

PouryaNoufallah96 avatar PouryaNoufallah96 commented on June 11, 2024 1

the problem was this line in minimal API endpoint file:

        var group = app.MapGroup(Routes.Personnel.MainUrl)
            .RequireAuthorization()
            .UseValidateOrganization(onlyOwner: false)
            .UseCheckMembership(needOrganizationInfo: true)
            **.WithGroupName(Routes.Personnel.Group);**

I removed .WithGroupName(Routes.Personnel.Group) and problem gone

from aspnet-api-versioning.

commonsensesoftware avatar commonsensesoftware commented on June 11, 2024 1

Glad you found a solution. You should be able to use a group name though. API Versioning will collate and use the API version as the group name by default, but you are supposed to be able override and/or combine the two. I don't messing with a lot of configurations for Minimal APIs, but it should work. As I recall WithGroupName should register the same metadata as [ApiExplorerSettings(GroupName="")]. I may need to take a peek to verify things are working correctly. Thanks for providing all of the details.

from aspnet-api-versioning.

commonsensesoftware avatar commonsensesoftware commented on June 11, 2024

This isn't very much information to go on. What's the error? It will be reported to the console. My initial guess is that there are two or more types with the same name, but in different .NET namespaces. A namespace is meaningless to an OpenAPI document and will lead to a naming collision.

Sharing a repro or, at least, your configuration would be helpful.

from aspnet-api-versioning.

PouryaNoufallah96 avatar PouryaNoufallah96 commented on June 11, 2024

thanks for your response.

no, it does not return any error. this is the console result after running the application:
[15:25:04 INF] Executing endpoint 'HTTP: GET /'
[15:25:04 INF] Executing RedirectResult, redirecting to /swagger.
[15:25:04 INF] Executed endpoint 'HTTP: GET /'
[15:25:04 INF] Request finished HTTP/1.1 GET http://localhost:5004/ - 302 0 null 202.2194ms
[15:25:04 INF] Request starting HTTP/1.1 GET http://localhost:5004/swagger - null null
[15:25:04 INF] Request finished HTTP/1.1 GET http://localhost:5004/swagger - 301 0 null 3.7115ms
[15:25:04 INF] Request starting HTTP/1.1 GET http://localhost:5004/swagger/index.html - null null
[15:25:04 INF] Request finished HTTP/1.1 GET http://localhost:5004/swagger/index.html - 200 null text/html;charset=utf-8 85.4436ms
[15:25:04 INF] Request starting HTTP/1.1 GET http://localhost:5004/swagger/v1/swagger.json - not found

this is my configuration :

        services
            .AddApiVersioning(options =>
            {
                options.ReportApiVersions = true;
                options.AssumeDefaultVersionWhenUnspecified = true;
                options.DefaultApiVersion = new ApiVersion(1, 0);
                options.ApiVersionReader = new UrlSegmentApiVersionReader();
            })
            .AddMvc()
            .AddApiExplorer(setup =>
            {
                setup.GroupNameFormat = "'v'V";
                setup.SubstituteApiVersionInUrl = true;
            })
            .EnableApiVersionBinding();

and for swagger:

        app.UseSwagger();

        app.UseSwaggerUI(c =>
        {
            var descriptions = app.DescribeApiVersions();
            foreach (var description in descriptions)
            {
                c.SwaggerEndpoint(
                    $"/swagger/{description.GroupName}/swagger.json",
                    description.GroupName.ToUpperInvariant()
                );
            }
        });

I'm not getting any errors this is why I'm confused and when I downgrade to the previous version everything just works fine

from aspnet-api-versioning.

commonsensesoftware avatar commonsensesoftware commented on June 11, 2024

The configuration looks ok. I presume you are using Minimal APIs; otherwise, you don't need EnableApiVersionBinding(). Which IDE are you using? VS? VS Code? If it's not going to the console, there should be something going the debug output. When I've see Swashbuckle errors in the past, that's how I determine the problem.

It might be worth checking the Break On All Exceptions option so that you see any First Chance Exceptions. If you can't see or find an error, is there any way to get a bare bones repro? An exception is happening, but I don't know what it is or how to help you find it. Once I know that the error is, I can provide more guidance.

from aspnet-api-versioning.

PouryaNoufallah96 avatar PouryaNoufallah96 commented on June 11, 2024

I checked with vs and rider and vscode and yes I'm using minimal API. couldn't get any exceptions and I put breakpoints every where Nothing was wrong in the console and debug too.
also, my APIs are working when I test them with Postman.

from aspnet-api-versioning.

commonsensesoftware avatar commonsensesoftware commented on June 11, 2024

Gotcha. Yes, the would work when the APIs are called directly. This is specifically limited to generating the OpenAPI document via Swashbuckle. My recommendation would be to comment all of the APIs save one. Run it and make sure the OpenAPI document is generated and the Swagger UI comes up. Assuming that works, continue uncommenting one API at a time until you find the offending API that is causing the problem. If you can share the signatures or definitions of the offending APIs, I might be able to provide better direction.

from aspnet-api-versioning.

PouryaNoufallah96 avatar PouryaNoufallah96 commented on June 11, 2024

this is how i configure my minimal apis for versioning:

        var apiVersionSet = app.NewApiVersionSet()
            .HasApiVersion(new ApiVersion(1, 0))
            .ReportApiVersions()
            .Build();

        var versionedGroup = app.MapGroup($"api/v{version:apiVersion}")
            .WithApiVersionSet(apiVersionSet);

        app.MapMinimalApis(versionedGroup);
        

And I register them using reflection:

   public static void MapMinimalApis(this WebApplication app, RouteGroupBuilder? routeGroupBuilder = null)
   {
       var endpoints = app.Services.GetRequiredService<IEnumerable<IEndpointDefinition>>();

       IEndpointRouteBuilder builder = routeGroupBuilder is null ? app : routeGroupBuilder;

       foreach (var endpoint in endpoints)
       {
           endpoint.ConfigureEndpoints(builder);
       }
   }

and this is one of my endpoints:

public class UserEndpoints : EndpointResponseHandler, IEndpointDefinition
{
    private static readonly List<OpenApiTag> _tags = [new OpenApiTag { Name = Routes.User.Group },];

    public void ConfigureEndpoints(IEndpointRouteBuilder app)
    {
        var group = app.MapGroup(Routes.User.MainUrl)
            .RequireAuthorization()
            .UseValidateOrganization(onlyOwner: true)
            .UseCheckMembership(needOrganizationInfo: false)
            .WithGroupName(Routes.User.Group);

        group
            .MapPost(Routes.User.AddUserByMember, AddUserByMember)
            .Produces<bool>()
            .ProducesValidationProblem()
            .ProducesProblem(StatusCodes.Status400BadRequest)
            .ProducesProblem(StatusCodes.Status401Unauthorized)
            .ProducesProblem(StatusCodes.Status403Forbidden)
            .ProducesProblem(StatusCodes.Status404NotFound)
            .ProducesProblem(StatusCodes.Status500InternalServerError)
            .WithName(nameof(AddUserByMember))
            .WithTags(Routes.User.Group)
            .WithOpenApi(x => new OpenApiOperation(x)
            {
                Summary = "Add User By Member",
                Description =
                    "Add a user by a member and if the user already exists, if will only assign the user to the organization.",
                Tags = _tags
            });
    }

    #region Handlers

    private static Task<Results<Ok<bool>, ProblemHttpResult>> AddUserByMember(
        [AsParameters] BaseEndpointServices services,
        AddUserByMemberCommand command
    ) =>
        Result
            .Create(command)
            .Map(services.IdentifiedCommandFactory.Create<AddUserByMemberCommand, Result<bool>>)
            .Bind(identifiedCommand => services.Sender.Send(identifiedCommand, services.CancellationToken))
            .Match<bool, Results<Ok<bool>, ProblemHttpResult>>(
                onSuccess: result => EndpointSucceedOk(result),
                onFailure: error => EndpointFailed(error)
            );

    #endregion
}

so I kept only this API and also commented all the open API related things like WithOpenApi(...) and all but when I run the app it will immediately show Not Found /swagger/v1/swagger.json

from aspnet-api-versioning.

PouryaNoufallah96 avatar PouryaNoufallah96 commented on June 11, 2024

i wonder maybe there's something wrong with this but there's no error any where

swagger doc configurations:

services.AddSwaggerGen();

       services.AddTransient<IConfigureOptions<SwaggerGenOptions>, ConfigureSwaggerOptions>(
           provider => new ConfigureSwaggerOptions(
               provider.GetRequiredService<IApiVersionDescriptionProvider>(),
               apiAssemblyMarkerType,
               apiName,
               headers
           )
       );

and ConfigureOptions:

public class ConfigureSwaggerOptions : IConfigureNamedOptions<SwaggerGenOptions>
{
    private const string AuthorizationFormat = "JWT";
    private const string OpenApiSecurityName = "Authorization";

    private readonly IApiVersionDescriptionProvider _provider;
    private readonly Assembly _apiAssembly;
    private readonly string _apiName;
    private readonly List<string>? _headers;

    public ConfigureSwaggerOptions(
        IApiVersionDescriptionProvider provider,
        Assembly apiAssemblyMarkerType,
        string apiName,
        List<string>? headers
    )
    {
        _provider = provider;
        _apiAssembly = apiAssemblyMarkerType;
        _apiName = apiName;
        _headers = headers;
    }

    public void Configure(SwaggerGenOptions options)
    {
        foreach (var description in _provider.ApiVersionDescriptions)
        {
            options.OperationFilter<ReApplyOptionalRouteParameterOperationFilter>();
            options.SwaggerDoc(description.GroupName, CreateVersionInfo(description, _apiName));
        }

        options.TagActionsBy(api =>
        {
            if (api.GroupName != null)
            {
                return [api.GroupName];
            }

            if (api.ActionDescriptor is ControllerActionDescriptor controllerActionDescriptor)
            {
                return [controllerActionDescriptor.ControllerName];
            }

            throw new InvalidOperationException("Unable to determine tag for endpoint.");
        });

        options.DocInclusionPredicate((_, _) => true);

        options.AddSecurityDefinition(
            SwaggerConstants.AuthSchema,
            new OpenApiSecurityScheme
            {
                Name = OpenApiSecurityName,
                Type = SecuritySchemeType.ApiKey,
                Scheme = SwaggerConstants.AuthSchema,
                BearerFormat = AuthorizationFormat,
                In = ParameterLocation.Header,
                Description = "JWT Authorization header using the Bearer scheme.",
            }
        );

        options.OperationFilter<AuthOperationFilter>();

        options.OperationFilter<SwaggerDefaultValuesFilter>();

        options.OperationFilter<AddRequiredHeaderParameterFilter>(_headers);

        var xmlFile = $"{_apiAssembly.GetName().Name}.xml";
        var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
        options.IncludeXmlComments(xmlPath);
    }

    public void Configure(string? name, SwaggerGenOptions options)
    {
        Configure(options);
    }

    private static OpenApiInfo CreateVersionInfo(ApiVersionDescription description, string apiName)
    {
        var info = new OpenApiInfo() { Title = apiName, Version = description.ApiVersion.ToString() };

        if (description.IsDeprecated)
        {
            info.Description +=
                " This API version has been deprecated. Please use one of the new APIs available from the explorer.";
        }

        return info;
    }
}

from aspnet-api-versioning.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.