Comments (6)
Have used this in the Startup.cs:
services.AddApiVersioning(config =>
{
// if we don't specify an api version, assume the default version is 1.0
config.DefaultApiVersion = new ApiVersion(1, 0);
// if api version is not specified assume default version to be the one we specified earlier
config.AssumeDefaultVersionWhenUnspecified = true;
// so that we can get an api version information in the responses
config.ReportApiVersions = true;
});
from aspnet-api-versioning.
It appears you are missing the call to AddMvc()
. With the introduction of Minimal APIs, AddApiVersioning()
only provides support for bare metal by default now. AddMvc()
will add the controller support. This is dependent upon MVC Core (as it always has been and not the full MVC stack (as some people have thought).
Revised Startup.cs
:
services.AddApiVersioning(config =>
{
// if we don't specify an api version, assume the default version is 1.0
config.DefaultApiVersion = new ApiVersion(1, 0);
// if api version is not specified assume default version to be the one we specified earlier
config.AssumeDefaultVersionWhenUnspecified = true;
// so that we can get an api version information in the responses
config.ReportApiVersions = true;
}).AddMvc(); // ← add MVC Core to support controllers
IApiVersioningBuilder.AddMvc
(API Versioning) should not be confused with IServiceCollection.AddMvc
. (ASP.NET Core). They do different things.
from aspnet-api-versioning.
I did add that was advised, but this is still not working for the ControllerName
attribute that I have already had, in the above example:
http://localhost:44362/api/Attributes/ListAllEndpoints
But it does seem to ignore the number in the controller name if present.
from aspnet-api-versioning.
Thanks for all of the details. I've been able to repro your scenario, which was a bit surprising. I thought maybe I somehow introduced a "new" bug, but nothing has changed in this area in a long, long time; not even from 5.1.0
to 6.0.0
.
I was able to figure out why this is happening. The ControllerNameAttribute
just explicitly sets the "controller"
route parameter value. At some point in time, this definitely worked as expected. I've tried to track down when things might have gone sideways. I've tried against both the new and old library builds, but I get the same results.
Poking around in the ASP.NET Core source, I see this addition from 5 years ago:
This code uses the ControllerActionDescriptor.ControllerName
as the value for the "controller"
route parameter and does not allow it to be overridden. As a result, ControllerNameAttribute
ends up having no effect.
The ControllerNameAttribute
was originally meant to solve problems related to convention-based routing; particularly in OData. Attribute routing doesn't have that problem because you explicitly define the route template. I did find some OData code in the old library that would have leveraged ControllerNameAttribute
correctly a la:
if ( controller.RouteValues.TryGetValue( "controller", out var name ) )
{
controller.ControllerName = name;
}
It would seem the correct path is to add this logic back into the place where IControllerNameConvention.NormalizeName
is used. This is the place where Info2
would become Info
in your example. If you specify ControllerNameAttribute
, then that value should be used verbatim without any normalization. In a simple test run, things indeed work as expected.
The crazy part is that this investigation seems to suggest that things have been broken for 5+ years. 😬 The reason it hasn't been detected is likely because the test cases use similar names rather than completely different ones; for example, "Info2Controller" -> "Info"
(verbatim; not normalized) vs "Info2Controller" -> "Attributes"
. I do think it should be "Attributes"
as you've articulated, but I'm really surprised this issue hasn't come up sooner.
The last part of this mystery is how you got it to work. You said that things were behaving as expected under 5.1.0
; however, I was not able to reproduce that behavior. I found that both libraries to have this issue. Do you have the world's simplest repro that shows your implementation working? Before I commit to the fix/change, I'd like to make sure I haven't missed something else. If you had used [ControllerName("Info")]
before and decided to change it to [ControllerName("Attributes")]
, then no repro should be needed; that would explain the discrepancy.
from aspnet-api-versioning.
Since I have been using this in a private repo, I may not be able to give too many details, but I do have a scenario where something similar used to work:
These are the two type of implementations that I had:
- A completely different name for Controller than the controller name:
namespace SomethingApi.Controllers.Console.DeveloperCommands;
[Route("api/v{version:apiVersion}/[controller]/[action]")]
[ApiController]
[ControllerName("console")]
[ApiVersion("1.0")]
[Authorize]
public class GenerateOTP : ControllerBase
{
private readonly OTPService otpService;
public GenerateOTP(OTPService otpService)
{
this.otpService = otpService;
}
[HttpGet]
public async Task<IActionResult> SendOTP()
{
var response = await otpService.SendOtp();
if (response.IsSuccess)
return Ok(response);
return BadRequest(response);
}
}
- Having two Controller with same name in a single namespace:
namespace SomethingApi.Controllers.v1;
[Route("api/v{version:apiVersion}/[controller]/[action]")]
[ApiController]
[Authorize]
[ControllerName("Attribute")]
[ApiVersion("2.0")]
public class Attribute2Controller : ControllerBase
{
private readonly AttributeService attributeService;
public Attribute2Controller(AttributeService attributeService)
{
this.attributeService = AttributeService;
}
[HttpGet]
public async Task<IActionResult> SearchAttributes([FromQuery] AttributeParameters filter)
{
....
return Ok(attribute);
}
}
[Route("api/v{version:apiVersion}/[controller]/[action]")]
[ApiController]
[Authorize]
[ApiVersion("1.0")]
public class AttributeController : ControllerBase
{
private readonly AttributeService attributeService;
public Attribute2Controller(AttributeService attributeService)
{
this.attributeService = AttributeService;
}
[HttpGet]
public async Task<IActionResult> FindAttributes([FromQuery] AttributeParameters filter)
{
....
return Ok(attribute);
}
}
I am also attaching the packages that I had installed when things were working for me:
I hope this will help you find anything else.
from aspnet-api-versioning.
I did check Just now:
- The first Implementation did not work previously either. I don't know when this got broken since I was not on the consumption end of the API.
api/v1.0/GenerateOTP/SendOtp
- But the second implementation was working fine since that was something I tested personally.
api/v2.0/Attribute/SearchAttributes
api/v1.0/Attribute/FindAttributes
from aspnet-api-versioning.
Related Issues (20)
- ASP.NET Web API versioning Migrate from QueryStringApiVersionReader to UrlSegmentApiVersionReader HOT 2
- only the 5.1.0 version of Microsoft.AspNetCore.Mvc.Versioning is deprecated HOT 3
- Problem with describing reponse codes in minimal api HOT 3
- Different options in `ApiVersioningOptions.cs` between .NET Framework and .NET Core packages HOT 2
- WithOpenApi() ignore Api versioning readers HOT 4
- .net 8 support HOT 7
- Breaking changes when migrating to OData8 + new versioning HOT 10
- odata/$metadata returns 404 when all controllers are decorated with ApiVersionNeutralAttribute HOT 3
- AddVersionedApiExplorer not working in Asp.Versioning HOT 5
- VersionedApiDescriptionProvider does not set the correct SunsetPolicy to ApiDescription instances HOT 1
- Using ApiExplorerSettingsAttribute together with ApiVersionAttribute produces unexpected number of ApiVersionDescriptions HOT 5
- Asp.Net Core WebApi - AWS ECS Cluster Authentication failure HOT 2
- [Versioned Clients][API Notifications] Fails to read new versions when available HOT 2
- Swashbuckle documentation inconsistent with examples HOT 2
- AssumeDefaultVersionWhenUnspecified does not work correctly if ApiVersionNeutral is used in the controller HOT 2
- swagger.json file not found after update HOT 9
- My API is not displaying all the versions. HOT 4
- Improve docs for HeaderApiVersionReader
- Add synonym to `AddMvc` method. HOT 7
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aspnet-api-versioning.