Skip to content

AddOpenApi and MapOpenApi() .net9 is generating docs for all the controller in the API. #62184

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

Closed
1 task done
GomesNayagam opened this issue May 30, 2025 · 1 comment
Closed
1 task done
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates feature-openapi

Comments

@GomesNayagam
Copy link

GomesNayagam commented May 30, 2025

Is there an existing issue for this?

  • I have searched the existing issues

Describe the bug

my dotnet core api migrated to .net9 and i was trying to enable new openapi spec but it is not generating for all the controller but just one.

when i analysze i see its return type is primitive and other controller return type is IActionResult

Expected Behavior

It should generate open api spec for all the controllers methods.

Steps To Reproduce

program.cs

services.AddOpenApi();
..
..
 app.MapOpenApi();
 app.MapScalarApiReference();

Exceptions (if any)

nil

.NET Version

9.0.204

Anything else?

Working one

namespace ExternalApi2.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ValueController : BaseController
    {
        public IConfiguration Configuration { get; }

        public ValueController(
            IConfiguration configuration,
            IHttpContextAccessor httpContextAccessor
        )
            : base(httpContextAccessor)
        {
            Configuration = configuration;
        }

        /// <summary>
        /// This API will return default values
        /// </summary>
        /// <remarks>
        /// This is used during production validlation to check if the server is responding
        /// </remarks>
        /// <response code="200">Will return default values</response>
        /// <response code="401">Unauthorized access will be returned if valid key is not passed in header, Please pass the key in header by cliking on  Authorize button(look up)</response>
        // GET: api/Value
        [HttpGet]
        [ProducesResponseType(typeof(string), StatusCodes.Status200OK)]
        [ProducesResponseType(typeof(string), StatusCodes.Status401Unauthorized)]
        [Produces("application/json")]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET: api/Value/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }

        // POST: api/Value
        [HttpPost]
        [ApiExplorerSettings(IgnoreApi = true)]
        public void Post([FromBody] string value) { }

        // PUT: api/Value/5
        [HttpPut]
        [ApiExplorerSettings(IgnoreApi = true)]
        public void Put(int id, [FromBody] string value) { }

        // DELETE: api/Value/5
        [HttpDelete]
        [ApiExplorerSettings(IgnoreApi = true)]
        public void Delete(int id) { }
    }
}

Not working one

namespace ExternalApi2.Controllers
{
    [Route("api/[controller]")]
    public class PolicyAuditController : BaseController
    {
        IAuditAppService _auditAppService;

        public PolicyAuditController(
            IHttpContextAccessor httpContextAccessor,
            IAuditAppService auditAppService
        )
            : base(httpContextAccessor)
        {
            _auditAppService = auditAppService;
        }

        /// <summary>
        /// Checks and returns data that indicates whether the policy is in audit or not, for the specified policy term.
        /// </summary>
        /// <remarks>
        /// Description: PolicyUnitNumber is mandatory, whereas PolicyYearDate is optional and if not provided, will return policy level audit details for all policy terms.
        /// Example: api/PolicyAudit?PolicyUnitNumber=9061173&amp;PolicyYearDate=2020
        ///  Note: Provide optional "UnitNumber" and "Year" Information in the request header to better assist you for issue resolution.
        /// </remarks>
        /// <param name="item"></param>
        /// <response code="200">Returns policy level audit status that indicates whether policy is in audit or not, for the specified policy term.</response>
        /// <response code="400">Occurs when validation failed when one or more of the following criteria satisfies.
        /// Code 1010 => Policy not found in PnP.</response>
        /// <response code="401">Unauthorized access</response>
        /// <response code="500">Occurs when there is an internal server error due to exceptions.</response>
        [HttpGet]
        [ProducesResponseType(typeof(PolicyAuditInfoDto), StatusCodes.Status200OK)]
        [ProducesResponseType(typeof(ValidationErrorDto), StatusCodes.Status400BadRequest)]
        [ProducesResponseType(typeof(string), StatusCodes.Status401Unauthorized)]
        [ProducesResponseType(
            typeof(ApplicationExceptionDto),
            StatusCodes.Status500InternalServerError
        )]
        [Produces("application/json")]
        public IActionResult Get(
            [Bind("GroupIdn,PolicyNumber,PolicyUnitNumber,PolicyYearDate,PolicySuffixCode")]
            [FromQuery]
                PolicyKeyDto objPolicyKey
        )
        {
            // var requestBody = Newtonsoft.Json.JsonConvert.SerializeObject(objPolicyKey);
            //  _loggerService.Info("PolicyAudit:" + requestBody, 0, objPolicyKey.PolicyUnitNumber);
            PolicyKeyDto policyKey = new PolicyKeyDto
            {
                GroupIdn = objPolicyKey.GroupIdn,
                PolicySuffixCode = objPolicyKey.PolicySuffixCode,
                PolicyUnitNumber = objPolicyKey.PolicyUnitNumber,
                PolicyYearDate = objPolicyKey.PolicyYearDate
            };
            var dto = _auditAppService.CheckPolicyinAudit(policyKey);
            if (dto == null || dto.HasValidationError || dto.HasApplicationException)
            {
                //  string response = Newtonsoft.Json.JsonConvert.SerializeObject(dto);
                //  _loggerService.Error(response, 0, policyKey.PolicyUnitNumber);
                return GenerateErrorResponse(dto);
            }
            else
            {
                return Ok(DataWrapper(dto));
            }
        }
    }
}
@github-actions github-actions bot added the needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically label May 30, 2025
@martincostello martincostello added area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates feature-openapi and removed needs-area-label Used by the dotnet-issue-labeler to label those issues which couldn't be triaged automatically labels May 30, 2025
@GomesNayagam
Copy link
Author

I Found the root cause it is caused by missing [ApiController] attribute, very strange and not mentioned anywhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-mvc Includes: MVC, Actions and Controllers, Localization, CORS, most templates feature-openapi
Projects
None yet
Development

No branches or pull requests

2 participants